Merge branch 'fix-opengraph-actor-preview' into 'master'
Fix opengraph actor preview See merge request framasoft/mobilizon!714
This commit is contained in:
commit
c28dae45bb
@ -181,26 +181,8 @@ config :http_signatures,
|
||||
|
||||
config :mobilizon, :cldr,
|
||||
locales: [
|
||||
"ar",
|
||||
"be",
|
||||
"ca",
|
||||
"cs",
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fi",
|
||||
"fr",
|
||||
"gl",
|
||||
"hu",
|
||||
"it",
|
||||
"ja",
|
||||
"nl",
|
||||
"nn",
|
||||
"oc",
|
||||
"pl",
|
||||
"pt",
|
||||
"ru",
|
||||
"sv"
|
||||
"en"
|
||||
]
|
||||
|
||||
config :mobilizon, :activitypub,
|
||||
|
@ -92,13 +92,6 @@ config :mobilizon, :instance,
|
||||
|
||||
# config :mobilizon, :activitypub, sign_object_fetches: false
|
||||
|
||||
# No need to compile every locale in development environment
|
||||
config :mobilizon, :cldr,
|
||||
locales: [
|
||||
"fr",
|
||||
"en"
|
||||
]
|
||||
|
||||
config :mobilizon, :anonymous,
|
||||
reports: [
|
||||
allowed: true
|
||||
|
@ -13,6 +13,31 @@ config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
# Do not print debug messages in production
|
||||
config :logger, level: :info
|
||||
|
||||
# Load all locales in production
|
||||
config :mobilizon, :cldr,
|
||||
locales: [
|
||||
"ar",
|
||||
"be",
|
||||
"ca",
|
||||
"cs",
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fi",
|
||||
"fr",
|
||||
"gl",
|
||||
"hu",
|
||||
"it",
|
||||
"ja",
|
||||
"nl",
|
||||
"nn",
|
||||
"oc",
|
||||
"pl",
|
||||
"pt",
|
||||
"ru",
|
||||
"sv"
|
||||
]
|
||||
|
||||
cond do
|
||||
System.get_env("INSTANCE_CONFIG") &&
|
||||
File.exists?("./config/#{System.get_env("INSTANCE_CONFIG")}") ->
|
||||
|
@ -5,6 +5,10 @@ defmodule Mobilizon.Cldr do
|
||||
|
||||
use Cldr,
|
||||
locales: Application.get_env(:mobilizon, :cldr)[:locales],
|
||||
gettext: Mobilizon.Web.Gettext,
|
||||
gettext:
|
||||
if(Application.fetch_env!(:mobilizon, :env) == :prod,
|
||||
do: Mobilizon.Web.Gettext,
|
||||
else: nil
|
||||
),
|
||||
providers: [Cldr.Number, Cldr.Calendar, Cldr.DateTime, Cldr.Language]
|
||||
end
|
||||
|
@ -32,7 +32,7 @@ defmodule Mobilizon.Service.Formatter.HTML do
|
||||
@spec strip_tags_and_insert_spaces(String.t()) :: String.t()
|
||||
def strip_tags_and_insert_spaces(html) when is_binary(html) do
|
||||
html
|
||||
|> String.replace("</", " </")
|
||||
|> String.replace("><", "> <")
|
||||
|> strip_tags()
|
||||
end
|
||||
|
||||
|
@ -4,20 +4,32 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Web.JsonLD.ObjectView
|
||||
alias Mobilizon.Web.MediaProxy
|
||||
import Mobilizon.Service.Metadata.Utils, only: [process_description: 2, default_description: 1]
|
||||
|
||||
def build_tags(_actor, _locale \\ "en")
|
||||
|
||||
def build_tags(%Actor{type: :Group} = group, locale) do
|
||||
default_desc = default_description(locale)
|
||||
|
||||
group =
|
||||
Map.update(group, :summary, default_desc, fn summary ->
|
||||
process_description(summary, locale)
|
||||
end)
|
||||
|
||||
def build_tags(%Actor{} = actor, _locale \\ "en") do
|
||||
[
|
||||
Tag.tag(:meta, property: "og:title", content: Actor.display_name_and_username(actor)),
|
||||
Tag.tag(:meta, property: "og:url", content: actor.url),
|
||||
Tag.tag(:meta, property: "og:description", content: actor.summary),
|
||||
Tag.tag(:meta, property: "og:title", content: Actor.display_name_and_username(group)),
|
||||
Tag.tag(:meta, property: "og:url", content: group.url),
|
||||
Tag.tag(:meta, property: "og:description", content: group.summary),
|
||||
Tag.tag(:meta, property: "og:type", content: "profile"),
|
||||
Tag.tag(:meta, property: "profile:username", content: actor.preferred_username),
|
||||
Tag.tag(:meta, property: "profile:username", content: group.preferred_username),
|
||||
Tag.tag(:meta, property: "twitter:card", content: "summary")
|
||||
]
|
||||
|> maybe_add_avatar(actor)
|
||||
|> maybe_add_group_schema(actor)
|
||||
|> maybe_add_avatar(group)
|
||||
|> add_group_schema(group)
|
||||
end
|
||||
|
||||
def build_tags(%Actor{} = _actor, _locale), do: []
|
||||
|
||||
@spec maybe_add_avatar(list(Tag.t()), Actor.t()) :: list(Tag.t())
|
||||
defp maybe_add_avatar(tags, actor) do
|
||||
if is_nil(actor.avatar) do
|
||||
@ -28,12 +40,10 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_add_group_schema(tags, %Actor{type: :Group} = group) do
|
||||
defp add_group_schema(tags, %Actor{} = group) do
|
||||
tags ++ [~s{<script type="application/ld+json">#{json(group)}</script>} |> HTML.raw()]
|
||||
end
|
||||
|
||||
defp maybe_add_group_schema(tags, _), do: tags
|
||||
|
||||
# Insert JSON-LD schema by hand because Tag.content_tag wants to escape it
|
||||
defp json(%Actor{} = group) do
|
||||
"group.json"
|
||||
|
@ -7,11 +7,15 @@ defmodule Mobilizon.Service.Metadata.Instance do
|
||||
alias Phoenix.HTML.Tag
|
||||
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Service.Formatter.HTML, as: HTMLFormatter
|
||||
alias Mobilizon.Service.Metadata.Utils
|
||||
alias Mobilizon.Web.Endpoint
|
||||
|
||||
@doc """
|
||||
Build the list of tags for the instance
|
||||
"""
|
||||
@spec build_tags() :: list(Phoenix.HTML.safe())
|
||||
def build_tags do
|
||||
description = process_description(Config.instance_description())
|
||||
description = Utils.process_description(Config.instance_description())
|
||||
title = "#{Config.instance_name()} - Mobilizon"
|
||||
|
||||
instance_json_ld = """
|
||||
@ -38,11 +42,4 @@ defmodule Mobilizon.Service.Metadata.Instance do
|
||||
HTML.raw(instance_json_ld)
|
||||
]
|
||||
end
|
||||
|
||||
defp process_description(description) do
|
||||
description
|
||||
|> HTMLFormatter.strip_tags()
|
||||
|> String.slice(0..200)
|
||||
|> (&"#{&1}…").()
|
||||
end
|
||||
end
|
||||
|
@ -1,7 +1,13 @@
|
||||
defprotocol Mobilizon.Service.Metadata do
|
||||
@doc """
|
||||
Build tags
|
||||
@moduledoc """
|
||||
Service that allows producing metadata HTML tags about content
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Build tags for an entity. Returns a list of `t:Phoenix.HTML.safe/0` tags.
|
||||
|
||||
Locale can be provided to generate fallback descriptions.
|
||||
"""
|
||||
@spec build_tags(any(), String.t()) :: list(Phoenix.HTML.safe())
|
||||
def build_tags(entity, locale \\ "en")
|
||||
end
|
||||
|
@ -9,28 +9,63 @@ defmodule Mobilizon.Service.Metadata.Utils do
|
||||
|
||||
@slice_limit 200
|
||||
|
||||
@spec stringify_tags(Enum.t()) :: String.t()
|
||||
@doc """
|
||||
Converts list of tags, containing either `t:Phoenix.HTML.safe/0` or strings, to a concatenated string listing the tags
|
||||
"""
|
||||
@spec stringify_tags(list(Phoenix.HTML.safe() | String.t())) :: String.t()
|
||||
def stringify_tags(tags), do: Enum.reduce(tags, "", &stringify_tag/2)
|
||||
|
||||
defp stringify_tag(tag, acc) when is_tuple(tag), do: acc <> HTML.safe_to_string(tag)
|
||||
defp stringify_tag(tag, acc) when is_binary(tag), do: acc <> tag
|
||||
|
||||
@doc """
|
||||
Removes the HTML tags from a text
|
||||
"""
|
||||
@spec strip_tags(String.t()) :: String.t()
|
||||
def strip_tags(text), do: HTMLFormatter.strip_tags(text)
|
||||
def strip_tags(text), do: HTMLFormatter.strip_tags_and_insert_spaces(text)
|
||||
|
||||
@doc """
|
||||
Processes a text and limits it.
|
||||
|
||||
* Removes the HTML tags from a text
|
||||
* Slices it to a limit and add an ellipsis character
|
||||
* Returns a default description if text is empty
|
||||
"""
|
||||
@spec process_description(String.t(), String.t(), integer()) :: String.t()
|
||||
def process_description(description, locale \\ "en", limit \\ @slice_limit)
|
||||
def process_description(nil, locale, limit), do: process_description("", locale, limit)
|
||||
|
||||
def process_description("", locale, _limit) do
|
||||
Gettext.put_locale(locale)
|
||||
gettext("The event organizer didn't add any description.")
|
||||
default_description(locale)
|
||||
end
|
||||
|
||||
def process_description(description, _locale, limit) do
|
||||
description
|
||||
|> HTMLFormatter.strip_tags()
|
||||
|> String.slice(0..limit)
|
||||
|> (&"#{&1}…").()
|
||||
|> HTMLFormatter.strip_tags_and_insert_spaces()
|
||||
|> String.trim()
|
||||
|> maybe_slice(limit)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the default description for a text
|
||||
"""
|
||||
@spec default_description(String.t()) :: String.t()
|
||||
def default_description(locale \\ "en") do
|
||||
Gettext.put_locale(locale)
|
||||
gettext("The event organizer didn't add any description.")
|
||||
end
|
||||
|
||||
defp maybe_slice(description, limit) do
|
||||
if String.length(description) > limit do
|
||||
description
|
||||
|> String.slice(0..limit)
|
||||
|> String.trim()
|
||||
|> (&"#{&1}…").()
|
||||
else
|
||||
description
|
||||
end
|
||||
end
|
||||
|
||||
@spec stringify_tag(Phoenix.HTML.safe(), String.t()) :: String.t()
|
||||
defp stringify_tag(tag, acc) when is_tuple(tag), do: acc <> HTML.safe_to_string(tag)
|
||||
|
||||
@spec stringify_tag(String.t(), String.t()) :: String.t()
|
||||
defp stringify_tag(tag, acc) when is_binary(tag), do: acc <> tag
|
||||
end
|
||||
|
24
test/service/metadata/instance_test.exs
Normal file
24
test/service/metadata/instance_test.exs
Normal file
@ -0,0 +1,24 @@
|
||||
defmodule Mobilizon.Service.Metadata.InstanceTest do
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Service.Metadata.{Instance, Utils}
|
||||
alias Mobilizon.Web.Endpoint
|
||||
use Mobilizon.DataCase
|
||||
|
||||
describe "build_tags/0 for the instance" do
|
||||
test "gives tags" do
|
||||
title = "#{Config.instance_name()} - Mobilizon"
|
||||
description = Utils.process_description(Config.instance_description())
|
||||
|
||||
assert Instance.build_tags() |> Utils.stringify_tags() ==
|
||||
"<title>#{title}</title><meta content=\"#{description}\" name=\"description\"><meta content=\"#{
|
||||
title
|
||||
}\" property=\"og:title\"><meta content=\"#{Endpoint.url()}\" property=\"og:url\"><meta content=\"#{
|
||||
description
|
||||
}\" property=\"og:description\"><meta content=\"website\" property=\"og:type\"><script type=\"application/ld+json\">{\n\"@context\": \"http://schema.org\",\n\"@type\": \"WebSite\",\n\"name\": \"#{
|
||||
title
|
||||
}\",\n\"url\": \"#{Endpoint.url()}\",\n\"potentialAction\": {\n\"@type\": \"SearchAction\",\n\"target\": \"#{
|
||||
Endpoint.url()
|
||||
}/search?term={search_term}\",\n\"query-input\": \"required name=search_term\"\n}\n}</script>\n"
|
||||
end
|
||||
end
|
||||
end
|
143
test/service/metadata/metadata_test.exs
Normal file
143
test/service/metadata/metadata_test.exs
Normal file
@ -0,0 +1,143 @@
|
||||
defmodule Mobilizon.Service.MetadataTest do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Service.Metadata
|
||||
alias Mobilizon.Tombstone
|
||||
use Mobilizon.DataCase
|
||||
import Mobilizon.Factory
|
||||
|
||||
describe "build_tags/2 for an actor" do
|
||||
test "that is a group gives tags" do
|
||||
%Actor{} = group = insert(:group, name: "My group")
|
||||
|
||||
assert group |> Metadata.build_tags() |> Metadata.Utils.stringify_tags() ==
|
||||
"<meta content=\"#{group.name} (@#{group.preferred_username})\" property=\"og:title\"><meta content=\"#{
|
||||
group.url
|
||||
}\" property=\"og:url\"><meta content=\"The event organizer didn't add any description.\" property=\"og:description\"><meta content=\"profile\" property=\"og:type\"><meta content=\"#{
|
||||
group.preferred_username
|
||||
}\" property=\"profile:username\"><meta content=\"summary\" property=\"twitter:card\"><meta content=\"#{
|
||||
group.avatar.url
|
||||
}\" property=\"og:image\"><script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"Organization\",\"address\":null,\"name\":\"#{
|
||||
group.name
|
||||
}\",\"url\":\"#{group.url}\"}</script>"
|
||||
|
||||
assert group
|
||||
|> Map.put(:avatar, nil)
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() ==
|
||||
"<meta content=\"#{group.name} (@#{group.preferred_username})\" property=\"og:title\"><meta content=\"#{
|
||||
group.url
|
||||
}\" property=\"og:url\"><meta content=\"The event organizer didn't add any description.\" property=\"og:description\"><meta content=\"profile\" property=\"og:type\"><meta content=\"#{
|
||||
group.preferred_username
|
||||
}\" property=\"profile:username\"><meta content=\"summary\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"Organization\",\"address\":null,\"name\":\"#{
|
||||
group.name
|
||||
}\",\"url\":\"#{group.url}\"}</script>"
|
||||
end
|
||||
|
||||
test "that is not a group doesn't give anything" do
|
||||
%Actor{} = person = insert(:actor)
|
||||
|
||||
assert person |> Metadata.build_tags() |> Metadata.Utils.stringify_tags() == ""
|
||||
assert person |> Metadata.build_tags("fr") |> Metadata.Utils.stringify_tags() == ""
|
||||
end
|
||||
end
|
||||
|
||||
describe "build_tags/2 for an event" do
|
||||
test "gives tags" do
|
||||
alias Mobilizon.Web.Endpoint
|
||||
|
||||
%Event{} = event = insert(:event)
|
||||
|
||||
# Because the description in Schema.org data is double-escaped
|
||||
a = "\n"
|
||||
b = "\\n"
|
||||
|
||||
assert event
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() ==
|
||||
"<title>#{event.title} - Mobilizon</title><meta content=\"#{event.description}\" name=\"description\"><meta content=\"#{
|
||||
event.title
|
||||
}\" property=\"og:title\"><meta content=\"#{event.url}\" property=\"og:url\"><meta content=\"#{
|
||||
event.description
|
||||
}\" property=\"og:description\"><meta content=\"website\" property=\"og:type\"><link href=\"#{
|
||||
event.url
|
||||
}\" rel=\"canonical\"><meta content=\"#{event.picture.file.url}\" property=\"og:image\"><meta content=\"summary_large_image\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"Event\",\"description\":\"#{
|
||||
String.replace(event.description, a, b)
|
||||
}\",\"endDate\":\"#{DateTime.to_iso8601(event.ends_on)}\",\"eventStatus\":\"https://schema.org/EventScheduled\",\"image\":[\"#{
|
||||
event.picture.file.url
|
||||
}\"],\"location\":{\"@type\":\"Place\",\"address\":{\"@type\":\"PostalAddress\",\"addressCountry\":\"My Country\",\"addressLocality\":\"My Locality\",\"addressRegion\":\"My Region\",\"postalCode\":\"My Postal Code\",\"streetAddress\":\"My Street Address\"},\"name\":\"#{
|
||||
event.physical_address.description
|
||||
}\"},\"name\":\"#{event.title}\",\"organizer\":{\"@type\":\"Person\",\"name\":\"#{
|
||||
event.organizer_actor.preferred_username
|
||||
}\"},\"performer\":{\"@type\":\"Person\",\"name\":\"#{
|
||||
event.organizer_actor.preferred_username
|
||||
}\"},\"startDate\":\"#{DateTime.to_iso8601(event.begins_on)}\"}</script>"
|
||||
|
||||
assert event
|
||||
|> Map.put(:picture, nil)
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() ==
|
||||
"<title>#{event.title} - Mobilizon</title><meta content=\"#{event.description}\" name=\"description\"><meta content=\"#{
|
||||
event.title
|
||||
}\" property=\"og:title\"><meta content=\"#{event.url}\" property=\"og:url\"><meta content=\"#{
|
||||
event.description
|
||||
}\" property=\"og:description\"><meta content=\"website\" property=\"og:type\"><link href=\"#{
|
||||
event.url
|
||||
}\" rel=\"canonical\"><meta content=\"summary_large_image\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"Event\",\"description\":\"#{
|
||||
String.replace(event.description, a, b)
|
||||
}\",\"endDate\":\"#{DateTime.to_iso8601(event.ends_on)}\",\"eventStatus\":\"https://schema.org/EventScheduled\",\"image\":[\"#{
|
||||
"#{Endpoint.url()}/img/mobilizon_default_card.png"
|
||||
}\"],\"location\":{\"@type\":\"Place\",\"address\":{\"@type\":\"PostalAddress\",\"addressCountry\":\"My Country\",\"addressLocality\":\"My Locality\",\"addressRegion\":\"My Region\",\"postalCode\":\"My Postal Code\",\"streetAddress\":\"My Street Address\"},\"name\":\"#{
|
||||
event.physical_address.description
|
||||
}\"},\"name\":\"#{event.title}\",\"organizer\":{\"@type\":\"Person\",\"name\":\"#{
|
||||
event.organizer_actor.preferred_username
|
||||
}\"},\"performer\":{\"@type\":\"Person\",\"name\":\"#{
|
||||
event.organizer_actor.preferred_username
|
||||
}\"},\"startDate\":\"#{DateTime.to_iso8601(event.begins_on)}\"}</script>"
|
||||
end
|
||||
end
|
||||
|
||||
describe "build_tags/2 for a post" do
|
||||
test "gives tags" do
|
||||
%Post{} = post = insert(:post)
|
||||
|
||||
assert post
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() ==
|
||||
"<meta content=\"#{post.title}\" property=\"og:title\"><meta content=\"#{post.url}\" property=\"og:url\"><meta content=\"#{
|
||||
Metadata.Utils.process_description(post.body)
|
||||
}\" property=\"og:description\"><meta content=\"article\" property=\"og:type\"><meta content=\"summary\" property=\"twitter:card\"><link href=\"#{
|
||||
post.url
|
||||
}\" rel=\"canonical\"><meta content=\"summary_large_image\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"Article\",\"author\":{\"@type\":\"Organization\",\"name\":\"#{
|
||||
post.attributed_to.preferred_username
|
||||
}\"},\"dateModified\":\"#{DateTime.to_iso8601(post.updated_at)}\",\"datePublished\":\"#{
|
||||
DateTime.to_iso8601(post.publish_at)
|
||||
}\",\"name\":\"My Awesome article\"}</script>"
|
||||
end
|
||||
end
|
||||
|
||||
describe "build_tags/2 for a comment" do
|
||||
test "gives tags" do
|
||||
%Comment{} = comment = insert(:comment)
|
||||
|
||||
assert comment
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() ==
|
||||
"<meta content=\"#{comment.actor.preferred_username}\" property=\"og:title\"><meta content=\"#{
|
||||
comment.url
|
||||
}\" property=\"og:url\"><meta content=\"#{comment.text}\" property=\"og:description\"><meta content=\"website\" property=\"og:type\"><meta content=\"summary\" property=\"twitter:card\">"
|
||||
end
|
||||
end
|
||||
|
||||
describe "build_tags/2 for a tombstone" do
|
||||
test "gives nothing" do
|
||||
%Tombstone{} = tombstone = insert(:tombstone)
|
||||
|
||||
assert tombstone
|
||||
|> Metadata.build_tags()
|
||||
|> Metadata.Utils.stringify_tags() == ""
|
||||
end
|
||||
end
|
||||
end
|
60
test/service/metadata/utils_test.exs
Normal file
60
test/service/metadata/utils_test.exs
Normal file
@ -0,0 +1,60 @@
|
||||
defmodule Mobilizon.Service.Metadata.UtilsTest do
|
||||
alias Mobilizon.Service.Metadata.Utils
|
||||
use Mobilizon.DataCase
|
||||
|
||||
describe "process_description/3" do
|
||||
test "process_description/3 strip tags" do
|
||||
assert Utils.process_description("<p>This is my biography</p>") == "This is my biography"
|
||||
end
|
||||
|
||||
test "process_description/3 cuts after a limit" do
|
||||
assert Utils.process_description("<p>This is my biography</p>", "fr", 10) ==
|
||||
"This is my…"
|
||||
end
|
||||
|
||||
test "process_description/3 cuts after the default limit" do
|
||||
assert Utils.process_description(
|
||||
"<h1>Biography</h1><p>It all started when someone wanted a <b>very long string</b> to be cut. However it's difficult to invent things to write when you've got nothing to say. Anyway, what's the deal here. We just need to reach 200 characters.",
|
||||
"fr"
|
||||
) ==
|
||||
"Biography It all started when someone wanted a very long string to be cut. However it's difficult to invent things to write when you've got nothing to say. Anyway, what's the deal here. We…"
|
||||
end
|
||||
|
||||
test "process_description/3 returns default if no description is provided" do
|
||||
assert Utils.process_description(nil) ==
|
||||
"The event organizer didn't add any description."
|
||||
|
||||
assert Utils.process_description("", "en") ==
|
||||
"The event organizer didn't add any description."
|
||||
end
|
||||
end
|
||||
|
||||
describe "default_description/1" do
|
||||
test "returns default description with a correct locale" do
|
||||
assert Utils.default_description("en") == "The event organizer didn't add any description."
|
||||
end
|
||||
|
||||
test "returns default description with no locale provided" do
|
||||
assert Utils.default_description() == "The event organizer didn't add any description."
|
||||
end
|
||||
end
|
||||
|
||||
describe "stringify_tags/1" do
|
||||
test "converts tags to string" do
|
||||
alias Phoenix.HTML.Tag
|
||||
|
||||
tag_1 = Tag.tag(:meta, property: "og:url", content: "one")
|
||||
tag_2 = "<meta content=\"two\" property=\"og:url\">"
|
||||
tag_3 = Tag.tag(:meta, property: "og:url", content: "three")
|
||||
|
||||
assert Utils.stringify_tags([tag_1, tag_2, tag_3]) ==
|
||||
"<meta content=\"one\" property=\"og:url\"><meta content=\"two\" property=\"og:url\"><meta content=\"three\" property=\"og:url\">"
|
||||
end
|
||||
end
|
||||
|
||||
describe "strip_tags/1" do
|
||||
test "removes tags from string" do
|
||||
assert Utils.strip_tags("<h1>Hello</h1><p>How are you</p>") == "Hello How are you"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user