An IndieWeb engine for a self-hostable website. https://koype.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

webmention_test.exs 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. defmodule Koype.WebmentionTest do
  2. alias Koype.Webmention, as: Subject
  3. use Koype.DataCase
  4. use ExVCR.Mock
  5. import Mock
  6. import Koype.Factory
  7. doctest Subject
  8. describe ".receive!/1" do
  9. test "stores new for model" do
  10. model = insert(:entry)
  11. source_uri = Faker.Internet.url()
  12. target_uri = Koype.Repo.Entry.get_uri(model)
  13. html = """
  14. <html>
  15. <body>
  16. <div class="h-entry">
  17. <a class="p-author h-card" href="/"><span class="p-name">#{Faker.Name.name()}</span></a>
  18. <a class="u-like-of" href="#{target_uri}">Wow</a>
  19. </div>
  20. </body>
  21. </html>
  22. """
  23. use_cassette :stub, uri: source_uri, body: html do
  24. assert {:ok, webmention} = Subject.receive!(source: source_uri, target: target_uri)
  25. assert webmention.source == source_uri
  26. assert webmention.target == URI.parse(target_uri).path
  27. assert webmention.type == "like"
  28. end
  29. end
  30. test "stores new for homepage mention" do
  31. source_uri = Faker.Internet.url()
  32. target_uri = Koype.host() <> "/"
  33. html = """
  34. <html>
  35. <body>
  36. <div class="h-entry">
  37. <a class="p-author h-card" href="/"><span class="p-name">#{Faker.Name.name()}</span></a>
  38. <a class="u-like-of" href="#{target_uri}">Wow</a>
  39. </div>
  40. </body>
  41. </html>
  42. """
  43. use_cassette :stub, uri: source_uri, body: html do
  44. assert {:ok, webmention} = Subject.receive!(source: source_uri, target: target_uri)
  45. assert webmention.source == source_uri
  46. assert webmention.target == "/"
  47. assert webmention.type == "like"
  48. end
  49. end
  50. test "updates existing - set to 410 / deleted" do
  51. model = insert(:entry)
  52. source_uri = Faker.Internet.url()
  53. target_uri = Koype.Repo.Entry.get_uri(model)
  54. webmention = insert(:webmention, source: source_uri, target: URI.parse(target_uri).path, type: "like")
  55. html =
  56. "<html><body><div class='h-entry'><a href='/' class='h-card u-url'><span class='p-name'>Hello</span></a></div></body></html>"
  57. use_cassette :stub, url: source_uri, body: html, status_code: 410 do
  58. assert {:ok, :gone} = Subject.receive!(source: source_uri, target: target_uri)
  59. refute Koype.Repo.get(Koype.Repo.Webmention, webmention.id)
  60. end
  61. end
  62. @tag skip: true
  63. test "updates existing - refreshes content" do
  64. model = insert(:entry)
  65. source_uri = Faker.Internet.url()
  66. target_uri = Koype.Repo.Entry.get_uri(model)
  67. webmention = insert(:webmention, source: source_uri, target: URI.parse(target_uri).path, type: "like")
  68. html =
  69. "<html><body><div class='h-entry'><a href='/' class='h-card u-url'><span class='p-name'>Hello</span></a></div></body></html>"
  70. use_cassette :stub, url: source_uri, body: html, status_code: 200 do
  71. assert {:ok, updated_webmention} = Subject.receive!(source: source_uri, target: target_uri)
  72. assert updated_webmention.id == webmention.id
  73. assert updated_webmention.type == "like"
  74. end
  75. end
  76. test "fails when MF2 of source fails" do
  77. model = insert(:entry)
  78. source_uri = Faker.Internet.url()
  79. target_uri = Koype.Repo.Entry.get_uri(model)
  80. use_cassette :stub, url: source_uri, status_code: 200 do
  81. with_mock(IndieWeb.MF2.Remote, [], fetch: fn _ -> {:error, :test_error} end, flush: fn _ -> :ok end) do
  82. assert {:error, :test_error} = Subject.receive!(source: source_uri, target: target_uri)
  83. end
  84. end
  85. end
  86. test "fails when target doesn't exist" do
  87. source_uri = Faker.Internet.url()
  88. target_uri = Faker.Internet.url()
  89. assert {:error, :webmention_receive_failure, [reason: :no_target]} =
  90. Subject.receive!(source: source_uri, target: target_uri)
  91. end
  92. test "fails when database fails out" do
  93. model = insert(:entry)
  94. source_uri = Faker.Internet.url()
  95. target_uri = Koype.Repo.Entry.get_uri(model)
  96. use_cassette :stub, url: source_uri, status_code: 200 do
  97. with_mocks([
  98. {Koype.Repo.Webmention, [], create: fn _ -> {:error, :test_error} end},
  99. {IndieWeb.MF2.Remote, [], fetch: fn _ -> {:error, :test_error} end, flush: fn _ -> :ok end}
  100. ]) do
  101. assert {:error, :test_error} = Subject.receive!(source: source_uri, target: target_uri)
  102. end
  103. end
  104. end
  105. test "fails when storage fails out" do
  106. model = insert(:entry)
  107. source_uri = Faker.Internet.url()
  108. target_uri = Koype.Repo.Entry.get_uri(model)
  109. html =
  110. "<html><body><div class='h-entry'><a href='/' class='h-card u-url'><span class='p-name'>Hello</span></a><p class='p-content'>Wow</p></div></body></html>"
  111. use_cassette :stub, url: source_uri, body: html, status_code: 200 do
  112. with_mock(Koype.Storage.Json, persist: fn _, _ -> {:error, :test_storage_error} end) do
  113. assert {:error, _} = Subject.receive!(source: source_uri, target: target_uri)
  114. end
  115. end
  116. end
  117. test "fails when unable to parse MF2 of source" do
  118. model = insert(:entry)
  119. source_uri = Faker.Internet.url()
  120. target_uri = Koype.Repo.Entry.get_uri(model)
  121. html = "<html></html>"
  122. use_cassette :stub, url: source_uri, body: html, status_code: 200 do
  123. assert {:error, :mf2_not_found} = Subject.receive!(source: source_uri, target: target_uri)
  124. end
  125. end
  126. test "fails when unable to parse MF2 of source when page down" do
  127. model = insert(:entry)
  128. source_uri = Faker.Internet.url()
  129. target_uri = Koype.Repo.Entry.get_uri(model)
  130. html = "<html></html>"
  131. use_cassette :stub, url: source_uri, body: html, status_code: 400 do
  132. assert {:error, [reason: :page_unavailable, raw: %Koype.Http.Response{}]} =
  133. Subject.receive!(source: source_uri, target: target_uri)
  134. end
  135. end
  136. end
  137. end