Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created rich_link_controller and functionalities #227

Merged
merged 21 commits into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9b4c95d
Created rich_link_controller and functionalities
MatheusBuss May 8, 2022
75213d6
Updated rich_link to accept markdown. Added pandex
MatheusBuss May 11, 2022
18097d6
Created rich_link_controller_test. Replaced query functions
MatheusBuss May 12, 2022
c8cf9a6
Using Elixir's views. Updated tests
MatheusBuss May 13, 2022
79b4a78
Moved sanitizer from controller to view
MatheusBuss May 13, 2022
dca921a
Moved moduledoc on rich_link_controller
MatheusBuss May 13, 2022
056e6a8
Added nginx.conf and nginx instructions
MatheusBuss May 17, 2022
65cd412
Added proxy_pass to /api/rich_link
MatheusBuss May 17, 2022
3f24d53
Updated url field for users and products
MatheusBuss May 17, 2022
7899402
Updated NGINX documentation
MatheusBuss May 24, 2022
ec17754
Made requested changes to code
MatheusBuss May 24, 2022
438adf8
Fixed title appearing in quotes
MatheusBuss May 24, 2022
1933e48
Fixed underline showing as <u></u> tag
MatheusBuss May 26, 2022
d7d99ad
Removed unecessary lines on rich_link template
MatheusBuss May 26, 2022
f99fbe3
Added default image to products
MatheusBuss May 26, 2022
bd5329a
Updated rich_link_controller_test
MatheusBuss May 26, 2022
683d35c
Added whatsapp to user agents list. Updated instructions
MatheusBuss May 27, 2022
228c491
Implemented community rich link as a fallback
MatheusBuss May 30, 2022
505eebb
Updated canonical URL
MatheusBuss May 31, 2022
b45d456
Accounted for null user names
MatheusBuss May 31, 2022
8e13c49
Updated default image for products
MatheusBuss May 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions lib/cambiatus_web/controllers/rich_link_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
defmodule CambiatusWeb.RichLinkController do
use CambiatusWeb, :controller

@moduledoc """
Get data and render html to be used for rich links (also known as Open Graphs).
These rich links show additional information about the website when shared on social media
and must be compliant with the [Open Grap Protocol](https://ogp.me/)
"""
lucca65 marked this conversation as resolved.
Show resolved Hide resolved

alias CambiatusWeb.Resolvers.{Accounts, Commune, Shop}
alias Cambiatus.Repo

def rich_link(conn, params) do
data =
case Map.get(params, "page") do
["shop", id] ->
product_rich_link(id)

["profile", account] ->
user_rich_link(account)

[] ->
community_rich_link(conn.host)

_ ->
send_resp(conn, 404, "Category not found")
end

case data do
{:ok, data} ->
render(conn, "rich_link.html", %{data: data})
lucca65 marked this conversation as resolved.
Show resolved Hide resolved

{:error, reason} ->
send_resp(conn, 404, reason)
end
end

def product_rich_link(id) do
case Shop.get_product(nil, %{id: id}, nil) do
{:ok, product} ->
product = Repo.preload(product, :images)
[image | _] = product.images
MatheusBuss marked this conversation as resolved.
Show resolved Hide resolved

{:ok,
%{
description: product.description,
title: product.title,
url: nil,
image: image.uri,
locale: nil
}}

{:error, reason} ->
{:error, reason}
end
end

def user_rich_link(account) do
case Accounts.get_user(nil, %{account: account}, nil) do
{:ok, user} ->
{:ok,
%{
description: user.bio,
title: user.name,
MatheusBuss marked this conversation as resolved.
Show resolved Hide resolved
url: user.email,
image: user.avatar,
locale: user.location
}}

{:error, reason} ->
{:error, reason}
end
end

def community_rich_link(community_subdomain) do
case Commune.find_community(%{}, %{subdomain: community_subdomain}, %{}) do
{:ok, community} ->
{:ok,
%{
description: community.description,
title: community.name,
url: community_subdomain,
image: community.logo,
locale: nil
}}

{:error, reason} ->
{:error, reason}
end
end
end
1 change: 1 addition & 0 deletions lib/cambiatus_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ defmodule CambiatusWeb.Router do
get("/chain/info", ChainController, :info)
post("/invite", InviteController, :invite)
get("/manifest", ManifestController, :manifest)
get("/rich_link/*page", RichLinkController, :rich_link)
lucca65 marked this conversation as resolved.
Show resolved Hide resolved

post("/paypal", PaypalController, :index)
end
Expand Down
1 change: 1 addition & 0 deletions lib/cambiatus_web/templates/layout/app.html.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= @inner_content %>
18 changes: 18 additions & 0 deletions lib/cambiatus_web/templates/rich_link/rich_link.html.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<html lang="en" class="h-full" >
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@_cambiatus">
<meta name="description" content="<%= md_to_txt(@data.description) %>">
<meta property="og:description" content="<%= md_to_txt(@data.description) %>">
<meta property="og:locale" content="<%= @data.locale %>">
<meta property="og:type" content="website">
<meta property="og:title" content="<%= @data.title %>">
<meta property="og:url" content="<%= @data.url %>">
<meta property="og:image" content="<%= @data.image %>">

<title>"<%= @data.title %>"</title>
</head>
16 changes: 16 additions & 0 deletions lib/cambiatus_web/views/rich_link_view.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule CambiatusWeb.RichLinkView do
use CambiatusWeb, :view

require Earmark
require HtmlSanitizeEx

def md_to_txt(markdown) do
with {:ok, string, _} <- Earmark.as_html(markdown) do
HtmlSanitizeEx.strip_tags(string)
|> String.trim()
MatheusBuss marked this conversation as resolved.
Show resolved Hide resolved
else
{:error, _} ->
""
end
end
end
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ defmodule Cambiatus.Mixfile do
{:ex_phone_number, "~> 0.2"},
{:number, "~> 1.0"},
{:earmark, "~> 1.4"},
{:html_sanitize_ex, "~> 1.4"},

# Email capabilities
{:swoosh, "~> 1.0"},
Expand Down
109 changes: 109 additions & 0 deletions test/cambiatus_web/controllers/rich_link_controller_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
defmodule CambiatusWeb.RichLinkControllerTest do
use Cambiatus.DataCase
use CambiatusWeb.ConnCase

alias Cambiatus.Repo

setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end

describe "RichLink" do
test "generate rich link for community",
%{conn: conn} do
# Insert community and extract data for the rich link
community =
insert(:community)
|> Repo.preload(:subdomain)

expected_data = %{
description: md_to_txt(community.description),
title: community.name,
url: community.subdomain.name,
image: community.logo,
locale: nil
}

# Submit GET request for a community rich link
conn =
%{conn | host: community.subdomain.name}
|> get("/api/rich_link")

response = html_response(conn, 200)

# Check http code 200 and if all the rich link fields are properly filled
assert conn.status == 200

Enum.each(expected_data, fn {k, v} ->
assert String.match?(response, ~r/meta property=\"og:#{k}\" content=\"#{v}/)
end)
end

test "generate rich link for user",
%{conn: conn} do
# Insert user and extract data for the rich link

user = insert(:user)

expected_data = %{
description: md_to_txt(user.bio),
title: user.name,
url: user.email,
image: user.avatar,
locale: user.location
}

# Submit GET request for a user rich link
conn = get(conn, "/api/rich_link/profile/#{user.account}")
response = html_response(conn, 200)

# Check http code 200 and if all the rich link fields are properly filled
assert conn.status == 200
lucca65 marked this conversation as resolved.
Show resolved Hide resolved

Enum.each(expected_data, fn {k, v} ->
assert String.match?(response, ~r/meta property=\"og:#{k}\" content=\"#{v}/)
end)
end

test "generate rich link for product",
%{conn: conn} do
# Insert product and extract data for the rich link

product =
insert(:product)
|> Repo.preload(:images)

[image | _] = product.images

expected_data = %{
description: md_to_txt(product.description),
title: product.title,
url: nil,
image: image.uri,
locale: nil
}

# Submit GET request for a product rich link
conn = get(conn, "/api/rich_link/shop/#{product.id}")
response = html_response(conn, 200)

# Check http code 200 and if all the rich link fields are properly filled
assert conn.status == 200

Enum.each(expected_data, fn {k, v} ->
assert String.match?(response, ~r/meta property=\"og:#{k}\" content=\"#{v}/)
end)
end
end

defp md_to_txt(markdown) do
# Convert markdown to plain text
with {:ok, string, _} <- Earmark.as_html(markdown) do
HtmlSanitizeEx.strip_tags(string)
|> String.trim()
else
{:error, _} ->
""
end
end
end