From ce98d5eb9b4d9c5a09b91a9d4d13bb48ba2b8453 Mon Sep 17 00:00:00 2001
From: Maxim Filippov <colixer@gmail.com>
Date: Sun, 2 Dec 2018 22:03:53 +0300
Subject: [PATCH] Parse user's bio on register

---
 lib/pleroma/user.ex                           | 16 +++++++++++
 lib/pleroma/web/twitter_api/twitter_api.ex    |  2 +-
 .../web/twitter_api/twitter_api_controller.ex | 17 ++---------
 .../twitter_api_controller_test.exs           |  5 ++--
 test/web/twitter_api/twitter_api_test.exs     | 28 +++++++++++++++++++
 5 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 76712b4bf..3bd92c157 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -4,6 +4,8 @@ defmodule Pleroma.User do
   import Ecto.{Changeset, Query}
   alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
   alias Comeonin.Pbkdf2
+  alias Pleroma.Formatter
+  alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
   alias Pleroma.Web.{OStatus, Websub, OAuth}
   alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
 
@@ -802,4 +804,18 @@ defmodule Pleroma.User do
         :error
     end
   end
+
+  def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) do
+    mentions = Formatter.parse_mentions(bio)
+    tags = Formatter.parse_tags(bio)
+
+    emoji =
+      (user.info.source_data["tag"] || [])
+      |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
+      |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
+        {String.trim(name, ":"), url}
+      end)
+
+    CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji)
+  end
 end
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 39a2974bb..c19a4f084 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -132,7 +132,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     params = %{
       nickname: params["nickname"],
       name: params["fullname"],
-      bio: params["bio"],
+      bio: User.parse_bio(params["bio"]),
       email: params["email"],
       password: params["password"],
       password_confirmation: params["confirm"]
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index ff644dd79..961250d92 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -448,27 +448,16 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
     User.Info.profile_update(user.info, info_params)
   end
 
-  defp add_profile_emoji(user, params) do
+  defp parse_profile_bio(user, params) do
     if bio = params["description"] do
-      mentions = Formatter.parse_mentions(bio)
-      tags = Formatter.parse_tags(bio)
-
-      emoji =
-        (user.info.source_data["tag"] || [])
-        |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
-        |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
-          {String.trim(name, ":"), url}
-        end)
-
-      bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
-      Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
+      Map.put(params, "bio", User.parse_bio(bio, user))
     else
       params
     end
   end
 
   def update_profile(%{assigns: %{user: user}} = conn, params) do
-    params = add_profile_emoji(user, params)
+    params = parse_profile_bio(user, params)
     info_cng = build_info_cng(user, params)
 
     with changeset <- User.update_changeset(user, params),
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index 89c176da7..a1eb09a05 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -949,18 +949,19 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   describe "POST /api/account/update_profile.json" do
     test "it updates a user's profile", %{conn: conn} do
       user = insert(:user)
+      user2 = insert(:user)
 
       conn =
         conn
         |> assign(:user, user)
         |> post("/api/account/update_profile.json", %{
           "name" => "new name",
-          "description" => "new description"
+          "description" => "hi @#{user2.nickname}"
         })
 
       user = Repo.get!(User, user.id)
       assert user.name == "new name"
-      assert user.bio == "new description"
+      assert user.bio == "hi <span><a class='mention' href='#{user2.ap_id}'>@<span>#{user2.nickname}</span></a></span>"
 
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index ec13b89d4..baeea5a9e 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -257,6 +257,34 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
              UserView.render("show.json", %{user: fetched_user})
   end
 
+  test "it registers a new user and parses mentions in the bio" do
+    data1 = %{
+      "nickname" => "john",
+      "email" => "john@gmail.com",
+      "fullname" => "John Doe",
+      "bio" => "test",
+      "password" => "bear",
+      "confirm" => "bear"
+    }
+
+    {:ok, user1} = TwitterAPI.register_user(data1)
+
+    data2 = %{
+      "nickname" => "lain",
+      "email" => "lain@wired.jp",
+      "fullname" => "lain iwakura",
+      "bio" => "@john test",
+      "password" => "bear",
+      "confirm" => "bear"
+    }
+
+    {:ok, user2} = TwitterAPI.register_user(data2)
+
+    expected_text = "<span><a class='mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test"
+
+    assert user2.bio == expected_text
+  end
+
   @moduletag skip: "needs 'registrations_open: false' in config"
   test "it registers a new user via invite token and returns the user." do
     {:ok, token} = UserInviteToken.create_token()
-- 
2.49.0