Commit 0b75e9e5 authored by James Laver's avatar James Laver

Merge branch 'feature/profile-header-images' into 'develop'

Add endpoint for user configurable header images

See merge request !12
parents 9b430ea1 4a67e4cc
Pipeline #64782952 passed with stages
in 9 minutes and 18 seconds
......@@ -43,6 +43,7 @@ defmodule MoodleNet.Accounts do
|> Map.delete(:password)
|> Map.delete("password")
|> set_default_icon()
|> set_default_image()
password = attrs[:password] || attrs["password"]
......@@ -75,26 +76,41 @@ defmodule MoodleNet.Accounts do
def update_user(actor, changes) do
{icon_url, changes} = Map.pop(changes, :icon)
{image_url, changes} = Map.pop(changes, :image)
{location_content, changes} = Map.pop(changes, :location)
{website, changes} = Map.pop(changes, :website)
icon = Query.new() |> Query.belongs_to(:icon, actor) |> Query.one()
image = Query.new() |> Query.belongs_to(:image, actor) |> Query.one()
location = Query.new() |> Query.belongs_to(:location, actor) |> Query.one()
attachment = Query.new() |> Query.belongs_to(:attachment, actor) |> Query.one()
# FIXME this should be a transaction
with {:ok, _icon} <- ActivityPub.update(icon, url: icon_url),
{:ok, _image} <- update_image(image, image_url, actor),
{:ok, _location} <- update_location(location, location_content, actor),
{:ok, _attachment} <- update_attachment(attachment, website, actor),
{:ok, actor} <- ActivityPub.update(actor, changes) do
# FIXME
actor =
ActivityPub.reload(actor)
|> Query.preload_assoc([:icon, :location, :attachment])
|> Query.preload_assoc([:icon, :image, :location, :attachment])
{:ok, actor}
end
end
defp update_image(image, url, actor) do
case image do
nil ->
with {:ok, image} <- ActivityPub.new(type: "Image", url: url),
{:ok, image} <- ActivityPub.insert(image),
{:ok, _} <- Alter.add(actor, :image, image),
do: {:ok, image}
image ->
ActivityPub.update(image, url: url)
end
end
defp update_location(nil, nil, _), do: {:ok, nil}
defp update_location(location, nil, _) do
......@@ -278,4 +294,11 @@ defmodule MoodleNet.Accounts do
attrs
end
end
defp set_default_image(%{image: _} = attrs), do: attrs
@default_image "https://images.unsplash.com/photo-1557943978-bea7e84f0e87?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60"
defp set_default_image(attrs) do
Map.put(attrs, :image, %{type: "Image", url: @default_image})
end
end
......@@ -25,7 +25,7 @@ defmodule MoodleNetWeb.GraphQL.UserResolver do
end
def create_user(%{user: attrs}, info) do
attrs = attrs |> set_icon() |> set_location() |> set_website()
attrs = attrs |> set_icon() |> set_image() |> set_location() |> set_website()
with {:ok, %{actor: actor, user: user}} <- MoodleNet.Accounts.register_user(attrs),
{:ok, token} <- MoodleNet.OAuth.create_token(user.id) do
......@@ -93,14 +93,14 @@ defmodule MoodleNetWeb.GraphQL.UserResolver do
def prepare_user([e | _] = list, fields) when APG.has_type(e, "Person") do
list
|> preload_assoc_cond([:icon, :location, :attachment], fields)
|> preload_assoc_cond([:icon, :image, :location, :attachment], fields)
|> preload_aspect_cond([:actor_aspect], fields)
|> Enum.map(&prepare(&1, fields))
end
def prepare_user(e, fields) when APG.has_type(e, "Person") do
e
|> preload_assoc_cond([:icon, :location, :attachment], fields)
|> preload_assoc_cond([:icon, :image, :location, :attachment], fields)
|> preload_aspect_cond([:actor_aspect], fields)
|> prepare_common_fields()
end
......
......@@ -56,6 +56,12 @@ defmodule MoodleNetWeb.GraphQL.MoodleNetSchema do
def set_icon(attrs), do: attrs
def set_image(%{image: url} = attrs) when is_binary(url) do
Map.put(attrs, :image, %{type: "Image", url: url})
end
def set_image(attrs), do: attrs
def set_location(%{location: location} = attrs) when is_binary(location) do
Map.put(attrs, :location, %{type: "Place", content: location})
end
......@@ -174,6 +180,7 @@ defmodule MoodleNetWeb.GraphQL.MoodleNetSchema do
|> Map.update!(:url, &List.first/1)
|> Map.update(:preferred_username, nil, &from_language_value/1)
|> Map.update(:icon, nil, &to_icon/1)
|> Map.update(:image, nil, &to_image/1)
|> Map.update(:location, nil, &to_location/1)
|> Map.put(:website, website)
|> Map.put(:followers_count, count_items(entity, :followers))
......@@ -205,6 +212,16 @@ defmodule MoodleNetWeb.GraphQL.MoodleNetSchema do
defp to_icon(_), do: nil
defp to_image([entity | _]) when APG.is_entity(entity) do
with [url | _] <- entity[:url] do
url
else
_ -> nil
end
end
defp to_image(_), do: nil
defp to_location([entity | _]) when APG.is_entity(entity) do
with %{} = content <- entity[:content] do
from_language_value(content)
......
......@@ -94,6 +94,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchema do
field(:location, :string)
field(:website, :string)
field(:icon, :string)
field(:image, :string)
field(:primary_language, :string)
field :joined_communities, :user_joined_communities_connection do
......@@ -192,6 +193,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchema do
field(:location, :string)
field(:website, :string)
field(:icon, :string)
field(:image, :string)
field(:primary_language, :string)
end
......@@ -203,6 +205,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchema do
field(:location, :string)
field(:website, :string)
field(:icon, :string)
field(:image, :string)
end
input_object :login_input do
......
......@@ -12,10 +12,12 @@ defmodule MoodleNet.AccountsTest do
describe "register_user" do
test "works" do
icon_attrs = Factory.attributes(:image)
image_attrs = Factory.attributes(:image)
attrs =
Factory.attributes(:user)
|> Map.put("icon", icon_attrs)
|> Map.put("image", image_attrs)
|> Map.put("extra_field", "extra")
Accounts.add_email_to_whitelist(attrs["email"])
......@@ -27,6 +29,8 @@ defmodule MoodleNet.AccountsTest do
assert [icon] = ret.actor[:icon]
assert [icon_attrs["url"]] == get_in(ret, [:actor, :icon, Access.at(0), :url])
assert [%{type: ["Object", "Place"]}] = ret.actor.location
assert [image] = ret.actor[:image]
assert [image_attrs["url"]] == get_in(ret, [:actor, :image, Access.at(0), :url])
assert_delivered_email(MoodleNet.Email.welcome(ret.user, ret.email_confirmation_token.token))
end
......@@ -45,6 +49,13 @@ defmodule MoodleNet.AccountsTest do
assert ["https://s.gravatar.com/avatar/7779b850ea05dbeca7fc39a910a77f21?d=identicon&r=g&s=80"] == get_in(actor, [:icon, Access.at(0), :url])
end
test "set default header image" do
attrs = Factory.attributes(:user, email: "karenk@moodle.com")
|> Map.delete("image")
assert {:ok, %{actor: actor}} = Accounts.register_user(attrs)
assert ["https://images.unsplash.com/photo-1557943978-bea7e84f0e87?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60"] == get_in(actor, [:image, Access.at(0), :url])
end
test "fails with invalid password values" do
attrs = Factory.attributes(:user) |> Map.delete("password")
......@@ -81,17 +92,19 @@ defmodule MoodleNet.AccountsTest do
describe "update_user/2" do
test "works" do
actor = Factory.actor(location: nil, attachment: nil)
actor = Factory.actor(location: nil, attachment: nil, image: nil)
attrs = %{
name: "name",
preferred_username: "username",
locale: "fr",
primary_language: "cz",
summary: "summary",
image: "https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971",
location: nil,
website: nil
}
assert {:ok, actor} = MoodleNet.Accounts.update_user(actor, attrs)
assert [%{url: ["https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971"], type: ["Object", "Image"]}] = actor.image
assert actor.name == %{"und" => attrs.name}
assert actor.summary == %{"und" => attrs.summary}
assert actor.preferred_username == attrs.preferred_username
......@@ -99,6 +112,9 @@ defmodule MoodleNet.AccountsTest do
assert actor["primary_language"] == "cz"
assert actor.location == []
assert {:ok, actor} = MoodleNet.Accounts.update_user(actor, %{image: "https://images.unsplash.com/photo-1557943978-bea7e84f0e87"})
assert [%{url: ["https://images.unsplash.com/photo-1557943978-bea7e84f0e87"]}] = actor.image
assert {:ok, actor} = MoodleNet.Accounts.update_user(actor, %{location: "location"})
assert [%{content: %{"und" => "location"}, type: ["Object", "Place"]}] = actor.location
......
......@@ -20,6 +20,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
summary: "Summary"
location: "MoodleNet"
icon: "https://imag.es/alexcastano"
image: "https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971"
email: "alexcastano@newworld.com"
password: "password"
primaryLanguage: "Elixir"
......@@ -39,6 +40,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
summary
location
icon
image
primaryLanguage
website
}
......@@ -65,6 +67,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
assert user["summary"] == "Summary"
assert user["location"] == "MoodleNet"
assert user["icon"] == "https://imag.es/alexcastano"
assert user["image"] == "https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971"
assert user["primaryLanguage"] == "Elixir"
assert user["website"] == "test.tld"
end
......@@ -181,6 +184,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
summary
location
icon
image
primaryLanguage
}
}
......@@ -204,6 +208,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
assert user["summary"] == actor.summary["und"]
assert user["location"] == get_in(actor, [:location, Access.at(0), :content, "und"])
assert user["icon"] == get_in(actor, [:icon, Access.at(0), :url, Access.at(0)])
assert user["image"] == get_in(actor, [:image, Access.at(0), :url, Access.at(0)])
assert user["primaryLanguage"] == actor["primary_language"]
end
......@@ -258,6 +263,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
location
website
icon
image
primaryLanguage
}
}
......@@ -278,6 +284,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
assert user["location"] == get_in(actor, [:location, Access.at(0), :content, "und"])
assert user["website"] == get_in(actor, [:attachment, Access.at(0), "value"])
assert user["icon"] == get_in(actor, [:icon, Access.at(0), :url, Access.at(0)])
assert user["image"] == get_in(actor, [:image, Access.at(0), :url, Access.at(0)])
assert user["primaryLanguage"] == actor["primary_language"]
end
......@@ -536,6 +543,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
summary: "Summary"
location: "MoodleNet"
icon: "https://imag.es/alexcastano"
image: "https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971"
primaryLanguage: "Elixir"
website: "test.tld"
}
......@@ -552,6 +560,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
location
website
icon
image
primaryLanguage
}
}
......@@ -574,6 +583,7 @@ defmodule MoodleNetWeb.GraphQL.UserSchemaTest do
assert user["location"] == "MoodleNet"
assert user["website"] == "test.tld"
assert user["icon"] == "https://imag.es/alexcastano"
assert user["image"] == "https://images.unsplash.com/flagged/photo-1551255868-86bbc8e0f971"
end
@tag :user
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment