Browse Source

feat(webmention): Update tests and change resolving method.

jackyalcine 9 months ago
parent
commit
19658c4fac
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 537A4F904B15268D

+ 49
- 14
lib/indieweb/webmention.ex View File

@@ -1,19 +1,19 @@
1 1
 # Koype: a IndieWeb-focused, single-tenant website engine for people.
2
-# 
2
+#
3 3
 # Copyright © 2019 Jacky Alciné <jacky.is@black.af>
4
-# 
4
+#
5 5
 # This file belongs to the Koype project.
6
-# 
6
+#
7 7
 # This program is free software: you can redistribute it and/or modify
8 8
 # it under the terms of the GNU Affero General Public License as published by
9 9
 # the Free Software Foundation, either version 3 of the License, or
10 10
 # (at your option) any later version.
11
-# 
11
+#
12 12
 # This program is distributed in the hope that it will be useful,
13 13
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 14
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 15
 # GNU Affero General Public License for more details.
16
-# 
16
+#
17 17
 # You should have received a copy of the GNU Affero General Public License
18 18
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 19
 defmodule IndieWeb.Webmention do
@@ -33,14 +33,12 @@ defmodule IndieWeb.Webmention do
33 33
 
34 34
   def resolve_target(target_uri) when is_binary(target_uri) do
35 35
     Enum.reduce_while(
36
-      [Koype.Repo.Entry, Koype.Repo.Category],
36
+      [&resolve_homepage_for_target/1, &resolve_model_for_target/1],
37 37
       {:error, :no_relevant_content},
38
-      fn module, acc ->
39
-        Logger.info("Using #{module} to look up model from the URI #{target_uri}.")
40
-
41
-        case module.resolve_from_uri(target_uri) do
42
-          {:ok, model} -> {:halt, {:ok, model}}
43
-          _ -> {:cont, acc}
38
+      fn approach, acc ->
39
+        case approach.(target_uri) do
40
+          {:error, _} -> {:cont, acc}
41
+          {:ok, _} = result -> {:halt, result}
44 42
         end
45 43
       end
46 44
     )
@@ -52,6 +50,43 @@ defmodule IndieWeb.Webmention do
52 50
 
53 51
   def resolve_target(nil), do: {:error, :not_applicable}
54 52
 
53
+  def resolve_homepage_for_target(target_uri) when is_binary(target_uri) do
54
+    current_host = Koype.host()
55
+
56
+    cond do
57
+      "/" == target_uri ->
58
+        Logger.info("#{target_uri} matches our homepage.")
59
+        {:ok, "/"}
60
+
61
+      URI.parse(current_host) == URI.parse(target_uri) ->
62
+        Logger.info("#{target_uri} matches our homepage directly.")
63
+        {:ok, "/"}
64
+
65
+      true ->
66
+        Logger.debug("The URI #{target_uri} is not our homepage (#{current_host}).")
67
+        {:error, :not_homepage}
68
+    end
69
+  end
70
+
71
+  def resolve_model_for_target(target_uri) when is_binary(target_uri) do
72
+    Enum.reduce_while(
73
+      [Koype.Repo.Entry, Koype.Repo.Category],
74
+      {:error, :no_mentionable_models},
75
+      fn module, acc ->
76
+        Logger.info("Using #{module} to look up model from the URI #{target_uri}.")
77
+
78
+        case module.resolve_from_uri(target_uri) do
79
+          {:ok, _} ->
80
+            resolved_target = URI.parse(target_uri).path
81
+            {:halt, {:ok, resolved_target}}
82
+
83
+          _ ->
84
+            {:cont, acc}
85
+        end
86
+      end
87
+    )
88
+  end
89
+
55 90
   @spec discover_webmention_endpoint(site :: binary()) :: {:ok, binary()} | {:error, :no_webmention_endpoints_found}
56 91
   def discover_webmention_endpoint(site) do
57 92
     [
@@ -172,11 +207,11 @@ defmodule IndieWeb.Webmention do
172 207
         end)
173 208
 
174 209
         with(
175
-          {:ok, _} <- resolve_target(target),
210
+          {:ok, resolved_target} <- resolve_target(target),
176 211
           {:ok, webmention_model} <-
177 212
             Koype.Repo.Webmention.upsert(
178 213
               source: source,
179
-              target: URI.parse(target).path,
214
+              target: resolved_target,
180 215
               type: Atom.to_string(type),
181 216
               mf2: entry_mf2
182 217
             )

+ 41
- 3
test/unit/indieweb/webmention_test.exs View File

@@ -59,9 +59,10 @@ defmodule IndieWeb.WebmentionTest do
59 59
   describe ".resolve_target/1" do
60 60
     test "finds the target model of the webmentions" do
61 61
       entry = insert(:entry)
62
-      webmention = insert(:webmention, target: Koype.Repo.Entry.get_uri(entry))
62
+      post_uri = URI.parse(Koype.Repo.Entry.get_uri(entry)).path
63
+      webmention = insert(:webmention, target: post_uri)
63 64
 
64
-      assert {:ok, ^entry} = Subject.resolve_target(webmention)
65
+      assert {:ok, post_uri} = Subject.resolve_target(webmention)
65 66
     end
66 67
 
67 68
     test "fails if no models are found" do
@@ -108,7 +109,7 @@ defmodule IndieWeb.WebmentionTest do
108 109
   end
109 110
 
110 111
   describe ".receive!/1" do
111
-    test "stores new" do
112
+    test "stores new for model" do
112 113
       mf2 = %{
113 114
         "rels" => %{},
114 115
         "items" => [
@@ -183,6 +184,43 @@ defmodule IndieWeb.WebmentionTest do
183 184
       end
184 185
     end
185 186
 
187
+    test "stores new for homepage mention" do
188
+      mf2 = %{
189
+        "rels" => %{},
190
+        "items" => [
191
+          %{
192
+            "type" => ["h-entry"],
193
+            "properties" => %{
194
+              "author" => [
195
+                %{
196
+                  "properties" => %{
197
+                    "name" => [Faker.Name.name()],
198
+                    "photo" => [Faker.Avatar.image_url()],
199
+                    "url" => [Faker.Internet.url()],
200
+                    "note" => [Faker.Lorem.sentence()]
201
+                  },
202
+                  "type" => ["h-card"]
203
+                }
204
+              ],
205
+              "like-of" => [Faker.Internet.url()]
206
+            }
207
+          }
208
+        ]
209
+      }
210
+
211
+      source_uri = Faker.Internet.url()
212
+      target_uri = Koype.host()
213
+
214
+      use_cassette :stub, uri: source_uri, code: 200 do
215
+        with_mock(IndieWeb.MF2.Remote, [], fetch: fn _ -> {:ok, mf2} end, flush: fn _ -> :ok end) do
216
+          assert {:ok, webmention} = Subject.receive!(source: source_uri, target: target_uri)
217
+          assert webmention.source == source_uri
218
+          assert webmention.target == "/"
219
+          assert webmention.type == "like"
220
+        end
221
+      end
222
+    end
223
+
186 224
     @tag skip: true
187 225
     test "updates existing - refreshes content" do
188 226
       mf2 = %{

+ 9
- 4
web/templates/settings/_view-webmention.html.eex View File

@@ -32,7 +32,12 @@
32 32
   <tbody class="lh-copy">
33 33
   <%= for webmention <- webmentions.entries do %>
34 34
     <%
35
-      {:ok, model} = IndieWeb.Webmention.resolve_target(webmention.target)
35
+      {type, name} = case webmention.target do
36
+        "/" -> {"mention", "Direct Mention"}
37
+        path ->
38
+          {:ok, model} = IndieWeb.Webmention.resolve_target(path)
39
+          {model.type, model.name}
40
+      end
36 41
     %>
37 42
     <tr>
38 43
       <td class="tc tl-l pv2 bb b--black-20 hide-child">
@@ -48,10 +53,10 @@
48 53
         </details>
49 54
       </td>
50 55
       <td class="tc tl-l pv2 bb b--black-20 hide-child v-top">
51
-        <i class="v-mid w1 h1 dib" data-feather="<%= Koype.Web.EntryView.icon_for_type(model.type) || "at-sign" %>"></i>
56
+        <i class="v-mid w1 h1 dib" data-feather="<%= Koype.Web.EntryView.icon_for_type(type) || "at-sign" %>"></i>
52 57
         <a class="gray link v-mid dib" href="<%= webmention.target %>">
53
-          <span class="dn db-l truncate measure-narrow"><%= model.name %></span>
54
-          <span class="db dn-l"><%= model.name %></span>
58
+          <span class="dn db-l truncate measure-narrow"><%= name %></span>
59
+          <span class="db dn-l"><%= name %></span>
55 60
         </a>
56 61
       </td>
57 62
       <td class="tc bb b--black-20 pv2 v-top">

Loading…
Cancel
Save