Skip to content
Snippets Groups Projects
Commit 9a8850eb authored by lain's avatar lain
Browse files

Basic status creation and retrieval.

parent 8de523c8
No related branches found
No related tags found
No related merge requests found
Showing
with 272 additions and 9 deletions
defmodule Pleroma.User do
use Ecto.Schema
alias Pleroma.User
schema "users" do
field :bio, :string
......@@ -7,7 +8,22 @@ defmodule Pleroma.User do
field :name, :string
field :nickname, :string
field :password_hash, :string
field :following, { :array, :string }, default: []
field :ap_id, :string
timestamps()
end
def ap_id(%User{nickname: nickname}) do
host =
Application.get_env(:pleroma, Pleroma.Web.Endpoint)
|> Keyword.fetch!(:url)
|> Keyword.fetch!(:host)
"https://#{host}/users/#{nickname}"
end
def ap_followers(%User{} = user) do
"#{ap_id(user)}/followers"
end
end
defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Repo
alias Pleroma.Activity
import Ecto.Query
def insert(map) when is_map(map) do
Repo.insert(%Activity{data: map})
end
def fetch_public_activities do
query = from activity in Activity,
where: fragment(~s(? @> '{"to": ["https://www.w3.org/ns/activitystreams#Public"]}'), activity.data)
Repo.all(query)
end
end
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
def to_map(activity, %{user: user}) do
content = get_in(activity.data, ["object", "content"])
%{
"id" => activity.id,
"user" => UserRepresenter.to_map(user),
"attentions" => [],
"statusnet_html" => content,
"text" => content,
"is_local" => true,
"is_post_verb" => true
}
end
end
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Repo
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
def create_status(user = %User{}, data = %{}) do
activity = %{
type: "Create",
to: [
User.ap_followers(user),
"https://www.w3.org/ns/activitystreams#Public"
],
actor: User.ap_id(user),
object: %{
type: "Note",
content: data.status
}
}
ActivityPub.insert(activity)
end
def fetch_public_statuses do
activities = ActivityPub.fetch_public_activities
Enum.map(activities, fn(activity) ->
actor = get_in(activity.data, ["actor"])
user = Repo.get_by!(User, ap_id: actor)
ActivityRepresenter.to_map(activity, %{user: user})
end)
end
end
defmodule Pleroma.Repo.Migrations.AddFollowingListToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add :following, :map
end
end
end
defmodule Pleroma.Repo.Migrations.AddApIdToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add :ap_id, :string
end
end
end
defmodule Pleroma.Builders.UserBuilder do
alias Pleroma.{User, Repo}
def build do
%User{
email: "test@example.org",
name: "Test Name",
nickname: "testname",
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "A tester.",
}
end
def insert do
Repo.insert(build())
end
end
defmodule Pleroma.Builders.ActivityBuilder do
alias Pleroma.Builders.UserBuilder
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.User
def public_and_non_public do
{:ok, user} = UserBuilder.insert
public = %{
"id" => 1,
"actor" => user.ap_id,
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"object" => %{
"type" => "Note",
"content" => "test"
}
}
non_public = %{
"id" => 2,
"actor" => user.ap_id,
"to" => [],
"object" => %{
"type" => "Note",
"content" => "test"
}
}
{:ok, public} = ActivityPub.insert(public)
{:ok, non_public} = ActivityPub.insert(non_public)
%{
public: public,
non_public: non_public,
user: user
}
end
end
defmodule Pleroma.Builders.UserBuilder do
alias Pleroma.{User, Repo}
def build do
%User{
email: "test@example.org",
name: "Test Name",
nickname: "testname",
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "A tester.",
ap_id: "some id"
}
end
def insert do
Repo.insert(build())
end
end
defmodule Pleroma.UserTest do
alias Pleroma.Builders.UserBuilder
alias Pleroma.User
use Pleroma.DataCase
test "ap_id returns the activity pub id for the user" do
host =
Application.get_env(:pleroma, Pleroma.Web.Endpoint)
|> Keyword.fetch!(:url)
|> Keyword.fetch!(:host)
user = UserBuilder.build
expected_ap_id = "https://#{host}/users/#{user.nickname}"
assert expected_ap_id == User.ap_id(user)
end
test "ap_followers returns the followers collection for the user" do
user = UserBuilder.build
expected_followers_collection = "#{User.ap_id(user)}/followers"
assert expected_followers_collection == User.ap_followers(user)
end
end
......@@ -2,6 +2,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
use Pleroma.DataCase
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Activity
alias Pleroma.Builders.{UserBuilder, ActivityBuilder}
describe "insertion" do
test "inserts a given map into the activity database" do
......@@ -14,4 +15,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "fetch activities" do
test "retrieves all public activities" do
%{user: user, public: public} = ActivityBuilder.public_and_non_public
activities = ActivityPub.fetch_public_activities
assert length(activities) == 1
assert Enum.at(activities, 0) == public
end
end
end
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
use Pleroma.DataCase
alias Pleroma.{User, Activity}
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
alias Pleroma.Builders.UserBuilder
test "an activity" do
{:ok, user} = UserBuilder.insert
content = "Some content"
activity = %Activity{
id: 1,
data: %{
"type" => "Create",
"to" => [
User.ap_followers(user),
"https://www.w3.org/ns/activitystreams#Public"
],
"actor" => User.ap_id(user),
"object" => %{
"type" => "Note",
"content" => content
}
}
}
expected_status = %{
"id" => activity.id,
"user" => UserRepresenter.to_map(user),
"is_local" => true,
"attentions" => [],
"statusnet_html" => content,
"text" => content,
"is_post_verb" => true
}
assert ActivityRepresenter.to_map(activity, %{user: user}) == expected_status
end
end
defmodule Pleroma.Web.TwitterAPI.ControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.{User, Repo}
alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
alias Pleroma.Builders.UserBuilder
describe "POST /api/account/verify_credentials" do
setup [:valid_user]
......@@ -20,14 +20,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end
defp valid_user(_context) do
user = %User{
email: "test@example.org",
name: "Test Name",
nickname: "testname",
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "A tester."
}
user = Repo.insert!(user)
{ :ok, user } = UserBuilder.insert
[user: user]
end
......
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
alias Pleroma.Builders.{UserBuilder, ActivityBuilder}
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.{Activity, User}
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
alias Pleroma.Web.ActivityPub.ActivityPub
test "create a status" do
user = UserBuilder.build
input = %{
status: "Hello again."
}
{ :ok, activity = %Activity{} } = TwitterAPI.create_status(user, input)
assert get_in(activity.data, [:object, :content]) == "Hello again."
assert get_in(activity.data, [:object, :type]) == "Note"
assert get_in(activity.data, [:actor]) == User.ap_id(user)
assert Enum.member?(get_in(activity.data, [:to]), User.ap_followers(user))
assert Enum.member?(get_in(activity.data, [:to]), "https://www.w3.org/ns/activitystreams#Public")
end
test "fetch public activities" do
%{ public: activity, user: user } = ActivityBuilder.public_and_non_public
statuses = TwitterAPI.fetch_public_statuses()
assert length(statuses) == 1
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: user})
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment