diff options
Diffstat (limited to 'test/web')
| -rw-r--r-- | test/web/activity_pub/activity_pub_controller_test.exs | 42 | ||||
| -rw-r--r-- | test/web/activity_pub/activity_pub_test.exs | 43 | ||||
| -rw-r--r-- | test/web/federator_test.exs | 101 | ||||
| -rw-r--r-- | test/web/instances/instance_test.exs | 107 | ||||
| -rw-r--r-- | test/web/instances/instances_test.exs | 112 | ||||
| -rw-r--r-- | test/web/ostatus/incoming_documents/delete_handling_test.exs | 7 | ||||
| -rw-r--r-- | test/web/ostatus/ostatus_controller_test.exs | 88 | ||||
| -rw-r--r-- | test/web/ostatus/ostatus_test.exs | 18 | ||||
| -rw-r--r-- | test/web/websub/websub_controller_test.exs | 62 | 
9 files changed, 501 insertions, 79 deletions
| diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 52e67f046..d3dd160dd 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -6,8 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do    use Pleroma.Web.ConnCase    import Pleroma.Factory    alias Pleroma.Web.ActivityPub.{UserView, ObjectView} -  alias Pleroma.{Object, Repo, User} -  alias Pleroma.Activity +  alias Pleroma.{Object, Repo, Activity, User, Instances}    setup_all do      Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -144,6 +143,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        :timer.sleep(500)        assert Activity.get_by_ap_id(data["id"])      end + +    test "it clears `unreachable` federation status of the sender", %{conn: conn} do +      data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + +      sender_url = data["actor"] +      Instances.set_consistently_unreachable(sender_url) +      refute Instances.reachable?(sender_url) + +      conn = +        conn +        |> assign(:valid_signature, true) +        |> put_req_header("content-type", "application/activity+json") +        |> post("/inbox", data) + +      assert "ok" == json_response(conn, 200) +      assert Instances.reachable?(sender_url) +    end    end    describe "/users/:nickname/inbox" do @@ -191,6 +207,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert response(conn, 200) =~ note_activity.data["object"]["content"]      end + +    test "it clears `unreachable` federation status of the sender", %{conn: conn} do +      user = insert(:user) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() +        |> Map.put("bcc", [user.ap_id]) + +      sender_host = URI.parse(data["actor"]).host +      Instances.set_consistently_unreachable(sender_host) +      refute Instances.reachable?(sender_host) + +      conn = +        conn +        |> assign(:valid_signature, true) +        |> put_req_header("content-type", "application/activity+json") +        |> post("/users/#{user.nickname}/inbox", data) + +      assert "ok" == json_response(conn, 200) +      assert Instances.reachable?(sender_host) +    end    end    describe "/users/:nickname/outbox" do diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index b826f5a1b..2ada4f2e5 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -7,11 +7,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.CommonAPI -  alias Pleroma.{Activity, Object, User} +  alias Pleroma.{Activity, Object, User, Instances}    alias Pleroma.Builders.ActivityBuilder    import Pleroma.Factory    import Tesla.Mock +  import Mock    setup do      mock(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -696,6 +697,46 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do      assert 3 = length(activities)    end +  describe "publish_one/1" do +    test_with_mock "it calls `Instances.set_unreachable` on target inbox on non-2xx HTTP response code", +                   Instances, +                   [:passthrough], +                   [] do +      actor = insert(:user) +      inbox = "http://404.site/users/nick1/inbox" + +      assert {:error, _} = +               ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + +      assert called(Instances.set_unreachable(inbox)) +    end + +    test_with_mock "it calls `Instances.set_unreachable` on target inbox on request error of any kind", +                   Instances, +                   [:passthrough], +                   [] do +      actor = insert(:user) +      inbox = "http://connrefused.site/users/nick1/inbox" + +      assert {:error, _} = +               ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + +      assert called(Instances.set_unreachable(inbox)) +    end + +    test_with_mock "it does NOT call `Instances.set_unreachable` if target is reachable", +                   Instances, +                   [:passthrough], +                   [] do +      actor = insert(:user) +      inbox = "http://200.site/users/nick1/inbox" + +      assert {:ok, _} = ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + +      refute called(Instances.set_unreachable(inbox)) +    end +  end +    def data_uri do      File.read!("test/fixtures/avatar_data_uri")    end diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index a49265c0c..c6d10ef78 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -3,8 +3,8 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.FederatorTest do -  alias Pleroma.Web.Federator -  alias Pleroma.Web.CommonAPI +  alias Pleroma.Web.{CommonAPI, Federator} +  alias Pleroma.Instances    use Pleroma.DataCase    import Pleroma.Factory    import Mock @@ -71,6 +71,103 @@ defmodule Pleroma.Web.FederatorTest do      end    end +  describe "Targets reachability filtering in `publish`" do +    test_with_mock "it federates only to reachable instances via AP", +                   Federator, +                   [:passthrough], +                   [] do +      user = insert(:user) + +      {inbox1, inbox2} = +        {"https://domain.com/users/nick1/inbox", "https://domain2.com/users/nick2/inbox"} + +      insert(:user, %{ +        local: false, +        nickname: "nick1@domain.com", +        ap_id: "https://domain.com/users/nick1", +        info: %{ap_enabled: true, source_data: %{"inbox" => inbox1}} +      }) + +      insert(:user, %{ +        local: false, +        nickname: "nick2@domain2.com", +        ap_id: "https://domain2.com/users/nick2", +        info: %{ap_enabled: true, source_data: %{"inbox" => inbox2}} +      }) + +      Instances.set_unreachable( +        URI.parse(inbox2).host, +        Instances.reachability_datetime_threshold() +      ) + +      {:ok, _activity} = +        CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"}) + +      assert called(Federator.enqueue(:publish_single_ap, %{inbox: inbox1})) +      refute called(Federator.enqueue(:publish_single_ap, %{inbox: inbox2})) +    end + +    test_with_mock "it federates only to reachable instances via Websub", +                   Federator, +                   [:passthrough], +                   [] do +      user = insert(:user) +      websub_topic = Pleroma.Web.OStatus.feed_path(user) + +      sub1 = +        insert(:websub_subscription, %{ +          topic: websub_topic, +          state: "active", +          callback: "http://pleroma.soykaf.com/cb" +        }) + +      sub2 = +        insert(:websub_subscription, %{ +          topic: websub_topic, +          state: "active", +          callback: "https://pleroma2.soykaf.com/cb" +        }) + +      Instances.set_consistently_unreachable(sub1.callback) + +      {:ok, _activity} = CommonAPI.post(user, %{"status" => "HI"}) + +      assert called(Federator.enqueue(:publish_single_websub, %{callback: sub2.callback})) +      refute called(Federator.enqueue(:publish_single_websub, %{callback: sub1.callback})) +    end + +    test_with_mock "it federates only to reachable instances via Salmon", +                   Federator, +                   [:passthrough], +                   [] do +      user = insert(:user) + +      remote_user1 = +        insert(:user, %{ +          local: false, +          nickname: "nick1@domain.com", +          ap_id: "https://domain.com/users/nick1", +          info: %{salmon: "https://domain.com/salmon"} +        }) + +      remote_user2 = +        insert(:user, %{ +          local: false, +          nickname: "nick2@domain2.com", +          ap_id: "https://domain2.com/users/nick2", +          info: %{salmon: "https://domain2.com/salmon"} +        }) + +      Instances.set_consistently_unreachable("domain.com") + +      {:ok, _activity} = +        CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"}) + +      assert called(Federator.enqueue(:publish_single_salmon, {remote_user2, :_, :_})) +      refute called(Federator.enqueue(:publish_single_websub, {remote_user1, :_, :_})) +    end +  end +    describe "Receive an activity" do      test "successfully processes incoming AP docs with correct origin" do        params = %{ diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs new file mode 100644 index 000000000..a158c0a42 --- /dev/null +++ b/test/web/instances/instance_test.exs @@ -0,0 +1,107 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Instances.InstanceTest do +  alias Pleroma.Repo +  alias Pleroma.Instances.Instance + +  use Pleroma.DataCase + +  import Pleroma.Factory + +  setup_all do +    config_path = [:instance, :federation_reachability_timeout_days] +    initial_setting = Pleroma.Config.get(config_path) + +    Pleroma.Config.put(config_path, 1) +    on_exit(fn -> Pleroma.Config.put(config_path, initial_setting) end) + +    :ok +  end + +  describe "set_reachable/1" do +    test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do +      instance = insert(:instance, unreachable_since: NaiveDateTime.utc_now()) + +      assert {:ok, instance} = Instance.set_reachable(instance.host) +      refute instance.unreachable_since +    end + +    test "keeps nil `unreachable_since` of existing matching Instance record having nil `unreachable_since`" do +      instance = insert(:instance, unreachable_since: nil) + +      assert {:ok, instance} = Instance.set_reachable(instance.host) +      refute instance.unreachable_since +    end + +    test "does NOT create an Instance record in case of no existing matching record" do +      host = "domain.org" +      assert nil == Instance.set_reachable(host) + +      assert [] = Repo.all(Ecto.Query.from(i in Instance)) +      assert Instance.reachable?(host) +    end +  end + +  describe "set_unreachable/1" do +    test "creates new record having `unreachable_since` to current time if record does not exist" do +      assert {:ok, instance} = Instance.set_unreachable("https://domain.com/path") + +      instance = Repo.get(Instance, instance.id) +      assert instance.unreachable_since +      assert "domain.com" == instance.host +    end + +    test "sets `unreachable_since` of existing record having nil `unreachable_since`" do +      instance = insert(:instance, unreachable_since: nil) +      refute instance.unreachable_since + +      assert {:ok, _} = Instance.set_unreachable(instance.host) + +      instance = Repo.get(Instance, instance.id) +      assert instance.unreachable_since +    end + +    test "does NOT modify `unreachable_since` value of existing record in case it's present" do +      instance = +        insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10)) + +      assert instance.unreachable_since +      initial_value = instance.unreachable_since + +      assert {:ok, _} = Instance.set_unreachable(instance.host) + +      instance = Repo.get(Instance, instance.id) +      assert initial_value == instance.unreachable_since +    end +  end + +  describe "set_unreachable/2" do +    test "sets `unreachable_since` value of existing record in case it's newer than supplied value" do +      instance = +        insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10)) + +      assert instance.unreachable_since + +      past_value = NaiveDateTime.add(NaiveDateTime.utc_now(), -100) +      assert {:ok, _} = Instance.set_unreachable(instance.host, past_value) + +      instance = Repo.get(Instance, instance.id) +      assert past_value == instance.unreachable_since +    end + +    test "does NOT modify `unreachable_since` value of existing record in case it's equal to or older than supplied value" do +      instance = +        insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10)) + +      assert instance.unreachable_since +      initial_value = instance.unreachable_since + +      assert {:ok, _} = Instance.set_unreachable(instance.host, NaiveDateTime.utc_now()) + +      instance = Repo.get(Instance, instance.id) +      assert initial_value == instance.unreachable_since +    end +  end +end diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs new file mode 100644 index 000000000..adb8560a7 --- /dev/null +++ b/test/web/instances/instances_test.exs @@ -0,0 +1,112 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.InstancesTest do +  alias Pleroma.Instances + +  use Pleroma.DataCase + +  setup_all do +    config_path = [:instance, :federation_reachability_timeout_days] +    initial_setting = Pleroma.Config.get(config_path) + +    Pleroma.Config.put(config_path, 1) +    on_exit(fn -> Pleroma.Config.put(config_path, initial_setting) end) + +    :ok +  end + +  describe "reachable?/1" do +    test "returns `true` for host / url with unknown reachability status" do +      assert Instances.reachable?("unknown.site") +      assert Instances.reachable?("http://unknown.site") +    end + +    test "returns `false` for host / url marked unreachable for at least `reachability_datetime_threshold()`" do +      host = "consistently-unreachable.name" +      Instances.set_consistently_unreachable(host) + +      refute Instances.reachable?(host) +      refute Instances.reachable?("http://#{host}/path") +    end + +    test "returns `true` for host / url marked unreachable for less than `reachability_datetime_threshold()`" do +      url = "http://eventually-unreachable.name/path" + +      Instances.set_unreachable(url) + +      assert Instances.reachable?(url) +      assert Instances.reachable?(URI.parse(url).host) +    end + +    test "returns true on non-binary input" do +      assert Instances.reachable?(nil) +      assert Instances.reachable?(1) +    end +  end + +  describe "filter_reachable/1" do +    test "keeps only reachable elements of supplied list" do +      host = "consistently-unreachable.name" +      url1 = "http://eventually-unreachable.com/path" +      url2 = "http://domain.com/path" + +      Instances.set_consistently_unreachable(host) +      Instances.set_unreachable(url1) + +      assert [url1, url2] == Instances.filter_reachable([host, url1, url2]) +    end +  end + +  describe "set_reachable/1" do +    test "sets unreachable url or host reachable" do +      host = "domain.com" +      Instances.set_consistently_unreachable(host) +      refute Instances.reachable?(host) + +      Instances.set_reachable(host) +      assert Instances.reachable?(host) +    end + +    test "keeps reachable url or host reachable" do +      url = "https://site.name?q=" +      assert Instances.reachable?(url) + +      Instances.set_reachable(url) +      assert Instances.reachable?(url) +    end + +    test "returns error status on non-binary input" do +      assert {:error, _} = Instances.set_reachable(nil) +      assert {:error, _} = Instances.set_reachable(1) +    end +  end + +  # Note: implementation-specific (e.g. Instance) details of set_unreachable/1 should be tested in implementation-specific tests +  describe "set_unreachable/1" do +    test "returns error status on non-binary input" do +      assert {:error, _} = Instances.set_unreachable(nil) +      assert {:error, _} = Instances.set_unreachable(1) +    end +  end + +  describe "set_consistently_unreachable/1" do +    test "sets reachable url or host unreachable" do +      url = "http://domain.com?q=" +      assert Instances.reachable?(url) + +      Instances.set_consistently_unreachable(url) +      refute Instances.reachable?(url) +    end + +    test "keeps unreachable url or host unreachable" do +      host = "site.name" +      Instances.set_consistently_unreachable(host) +      refute Instances.reachable?(host) + +      Instances.set_consistently_unreachable(host) +      refute Instances.reachable?(host) +    end +  end +end diff --git a/test/web/ostatus/incoming_documents/delete_handling_test.exs b/test/web/ostatus/incoming_documents/delete_handling_test.exs index c8fbff6cc..d97cd79f4 100644 --- a/test/web/ostatus/incoming_documents/delete_handling_test.exs +++ b/test/web/ostatus/incoming_documents/delete_handling_test.exs @@ -2,9 +2,16 @@ defmodule Pleroma.Web.OStatus.DeleteHandlingTest do    use Pleroma.DataCase    import Pleroma.Factory +  import Tesla.Mock +    alias Pleroma.{Repo, Activity, Object}    alias Pleroma.Web.OStatus +  setup do +    mock(fn env -> apply(HttpRequestMock, :request, [env]) end) +    :ok +  end +    describe "deletions" do      test "it removes the mentioned activity" do        note = insert(:note_activity) diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 954abf5fe..3145ca9a1 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -14,49 +14,51 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do      :ok    end -  test "decodes a salmon", %{conn: conn} do -    user = insert(:user) -    salmon = File.read!("test/fixtures/salmon.xml") - -    conn = -      conn -      |> put_req_header("content-type", "application/atom+xml") -      |> post("/users/#{user.nickname}/salmon", salmon) - -    assert response(conn, 200) -  end - -  test "decodes a salmon with a changed magic key", %{conn: conn} do -    user = insert(:user) -    salmon = File.read!("test/fixtures/salmon.xml") - -    conn = -      conn -      |> put_req_header("content-type", "application/atom+xml") -      |> post("/users/#{user.nickname}/salmon", salmon) - -    assert response(conn, 200) - -    # Set a wrong magic-key for a user so it has to refetch -    salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1") -    # Wrong key -    info_cng = -      User.Info.remote_user_creation(salmon_user.info, %{ -        magic_key: -          "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" -      }) - -    salmon_user -    |> Ecto.Changeset.change() -    |> Ecto.Changeset.put_embed(:info, info_cng) -    |> Repo.update() - -    conn = -      build_conn() -      |> put_req_header("content-type", "application/atom+xml") -      |> post("/users/#{user.nickname}/salmon", salmon) - -    assert response(conn, 200) +  describe "salmon_incoming" do +    test "decodes a salmon", %{conn: conn} do +      user = insert(:user) +      salmon = File.read!("test/fixtures/salmon.xml") + +      conn = +        conn +        |> put_req_header("content-type", "application/atom+xml") +        |> post("/users/#{user.nickname}/salmon", salmon) + +      assert response(conn, 200) +    end + +    test "decodes a salmon with a changed magic key", %{conn: conn} do +      user = insert(:user) +      salmon = File.read!("test/fixtures/salmon.xml") + +      conn = +        conn +        |> put_req_header("content-type", "application/atom+xml") +        |> post("/users/#{user.nickname}/salmon", salmon) + +      assert response(conn, 200) + +      # Set a wrong magic-key for a user so it has to refetch +      salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1") +      # Wrong key +      info_cng = +        User.Info.remote_user_creation(salmon_user.info, %{ +          magic_key: +            "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" +        }) + +      salmon_user +      |> Ecto.Changeset.change() +      |> Ecto.Changeset.put_embed(:info, info_cng) +      |> Repo.update() + +      conn = +        build_conn() +        |> put_req_header("content-type", "application/atom+xml") +        |> post("/users/#{user.nickname}/salmon", salmon) + +      assert response(conn, 200) +    end    end    test "gets a feed", %{conn: conn} do diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 403cc7095..0c63dd84d 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatusTest do    use Pleroma.DataCase    alias Pleroma.Web.OStatus    alias Pleroma.Web.XML -  alias Pleroma.{Object, Repo, User, Activity} +  alias Pleroma.{Object, Repo, User, Activity, Instances}    import Pleroma.Factory    import ExUnit.CaptureLog @@ -311,6 +311,22 @@ defmodule Pleroma.Web.OStatusTest do      refute User.following?(follower, followed)    end +  test "it clears `unreachable` federation status of the sender" do +    incoming_reaction_xml = File.read!("test/fixtures/share-gs.xml") +    doc = XML.parse_document(incoming_reaction_xml) +    actor_uri = XML.string_from_xpath("//author/uri[1]", doc) +    reacted_to_author_uri = XML.string_from_xpath("//author/uri[2]", doc) + +    Instances.set_consistently_unreachable(actor_uri) +    Instances.set_consistently_unreachable(reacted_to_author_uri) +    refute Instances.reachable?(actor_uri) +    refute Instances.reachable?(reacted_to_author_uri) + +    {:ok, _} = OStatus.handle_incoming(incoming_reaction_xml) +    assert Instances.reachable?(actor_uri) +    refute Instances.reachable?(reacted_to_author_uri) +  end +    describe "new remote user creation" do      test "returns local users" do        local_user = insert(:user) diff --git a/test/web/websub/websub_controller_test.exs b/test/web/websub/websub_controller_test.exs index 9cbcda063..6492df2a0 100644 --- a/test/web/websub/websub_controller_test.exs +++ b/test/web/websub/websub_controller_test.exs @@ -50,35 +50,37 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do      assert_in_delta NaiveDateTime.diff(websub.valid_until, NaiveDateTime.utc_now()), 100, 5    end -  test "handles incoming feed updates", %{conn: conn} do -    websub = insert(:websub_client_subscription) -    doc = "some stuff" -    signature = Websub.sign(websub.secret, doc) - -    conn = -      conn -      |> put_req_header("x-hub-signature", "sha1=" <> signature) -      |> put_req_header("content-type", "application/atom+xml") -      |> post("/push/subscriptions/#{websub.id}", doc) - -    assert response(conn, 200) == "OK" - -    assert length(Repo.all(Activity)) == 1 -  end - -  test "rejects incoming feed updates with the wrong signature", %{conn: conn} do -    websub = insert(:websub_client_subscription) -    doc = "some stuff" -    signature = Websub.sign("wrong secret", doc) - -    conn = -      conn -      |> put_req_header("x-hub-signature", "sha1=" <> signature) -      |> put_req_header("content-type", "application/atom+xml") -      |> post("/push/subscriptions/#{websub.id}", doc) - -    assert response(conn, 500) == "Error" - -    assert length(Repo.all(Activity)) == 0 +  describe "websub_incoming" do +    test "handles incoming feed updates", %{conn: conn} do +      websub = insert(:websub_client_subscription) +      doc = "some stuff" +      signature = Websub.sign(websub.secret, doc) + +      conn = +        conn +        |> put_req_header("x-hub-signature", "sha1=" <> signature) +        |> put_req_header("content-type", "application/atom+xml") +        |> post("/push/subscriptions/#{websub.id}", doc) + +      assert response(conn, 200) == "OK" + +      assert length(Repo.all(Activity)) == 1 +    end + +    test "rejects incoming feed updates with the wrong signature", %{conn: conn} do +      websub = insert(:websub_client_subscription) +      doc = "some stuff" +      signature = Websub.sign("wrong secret", doc) + +      conn = +        conn +        |> put_req_header("x-hub-signature", "sha1=" <> signature) +        |> put_req_header("content-type", "application/atom+xml") +        |> post("/push/subscriptions/#{websub.id}", doc) + +      assert response(conn, 500) == "Error" + +      assert length(Repo.all(Activity)) == 0 +    end    end  end | 
