mirror of
https://github.com/plausible/analytics.git
synced 2024-11-26 11:44:03 +03:00
Include tests for Captcha success/failure scenarios (#2344)
* Include tests for Captcha success/failure scenarios * DRY
This commit is contained in:
parent
aa97e9cf89
commit
e3ca3b32db
@ -11,3 +11,5 @@ ADMIN_USER_PWD=fakepassword
|
||||
ENABLE_EMAIL_VERIFICATION=true
|
||||
SELFHOST=false
|
||||
SITE_LIMIT=3
|
||||
HCAPTCHA_SITEKEY=test
|
||||
HCAPTCHA_SECRET=scottiger
|
||||
|
@ -4,18 +4,17 @@ defmodule PlausibleWeb.Captcha do
|
||||
@verify_endpoint "https://hcaptcha.com/siteverify"
|
||||
|
||||
def enabled? do
|
||||
!!sitekey()
|
||||
is_binary(sitekey())
|
||||
end
|
||||
|
||||
def sitekey() do
|
||||
Application.get_env(:plausible, :hcaptcha, [])
|
||||
|> Keyword.fetch!(:sitekey)
|
||||
Application.get_env(:plausible, :hcaptcha, [])[:sitekey]
|
||||
end
|
||||
|
||||
def verify(token) do
|
||||
if enabled?() do
|
||||
res =
|
||||
HTTPClient.post(
|
||||
HTTPClient.impl().post(
|
||||
@verify_endpoint,
|
||||
[{"content-type", "application/x-www-form-urlencoded"}],
|
||||
%{
|
||||
@ -25,9 +24,8 @@ defmodule PlausibleWeb.Captcha do
|
||||
)
|
||||
|
||||
case res do
|
||||
{:ok, %Finch.Response{status: 200, body: body}} ->
|
||||
json = Jason.decode!(body)
|
||||
json["success"]
|
||||
{:ok, %Finch.Response{status: 200, body: %{"success" => success}}} ->
|
||||
success
|
||||
|
||||
_ ->
|
||||
false
|
||||
@ -38,7 +36,6 @@ defmodule PlausibleWeb.Captcha do
|
||||
end
|
||||
|
||||
defp secret() do
|
||||
Application.get_env(:plausible, :hcaptcha, [])
|
||||
|> Keyword.fetch!(:secret)
|
||||
Application.get_env(:plausible, :hcaptcha, [])[:secret]
|
||||
end
|
||||
end
|
||||
|
66
test/plausible_web/captcha_test.exs
Normal file
66
test/plausible_web/captcha_test.exs
Normal file
@ -0,0 +1,66 @@
|
||||
defmodule PlausibleWeb.CaptchaTest do
|
||||
use Plausible.DataCase
|
||||
|
||||
import Mox
|
||||
setup :verify_on_exit!
|
||||
|
||||
alias PlausibleWeb.Captcha
|
||||
|
||||
describe "mocked payloads" do
|
||||
@failure Jason.decode!(~s/{"success":false,"error-codes":["invalid-input-response"]}/)
|
||||
@success Jason.decode!(~s/{"success":true}/)
|
||||
|
||||
test "returns false for non-success response" do
|
||||
expect(
|
||||
Plausible.HTTPClient.Mock,
|
||||
:post,
|
||||
fn "https://hcaptcha.com/siteverify",
|
||||
[{"content-type", "application/x-www-form-urlencoded"}],
|
||||
%{response: "bad", secret: "scottiger"} ->
|
||||
{:ok,
|
||||
%Finch.Response{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/json"}],
|
||||
body: @failure
|
||||
}}
|
||||
end
|
||||
)
|
||||
|
||||
refute Captcha.verify("bad")
|
||||
end
|
||||
|
||||
test "returns true for successful response" do
|
||||
expect(
|
||||
Plausible.HTTPClient.Mock,
|
||||
:post,
|
||||
fn "https://hcaptcha.com/siteverify",
|
||||
[{"content-type", "application/x-www-form-urlencoded"}],
|
||||
%{response: "good", secret: "scottiger"} ->
|
||||
{:ok,
|
||||
%Finch.Response{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/json"}],
|
||||
body: @success
|
||||
}}
|
||||
end
|
||||
)
|
||||
|
||||
assert Captcha.verify("good")
|
||||
end
|
||||
end
|
||||
|
||||
describe "with patched application env" do
|
||||
setup do
|
||||
original_env = Application.get_env(:plausible, :hcaptcha)
|
||||
Application.put_env(:plausible, :hcaptcha, sitekey: nil)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:plausible, :hcaptcha, original_env)
|
||||
end)
|
||||
end
|
||||
|
||||
test "returns true when disabled" do
|
||||
assert Captcha.verify("disabled")
|
||||
end
|
||||
end
|
||||
end
|
@ -4,6 +4,9 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
use Plausible.Repo
|
||||
import Plausible.TestUtils
|
||||
|
||||
import Mox
|
||||
setup :verify_on_exit!
|
||||
|
||||
describe "GET /register" do
|
||||
test "shows the register form", %{conn: conn} do
|
||||
conn = get(conn, "/register")
|
||||
@ -14,6 +17,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
|
||||
describe "POST /register" do
|
||||
test "registering sends an activation link", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
@ -29,6 +34,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "user is redirected to activate page after registration", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
@ -43,6 +50,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "creates user record", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
@ -57,6 +66,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "logs the user in", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
@ -71,6 +82,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "user is redirected to activation after registration", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
@ -83,6 +96,22 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
|
||||
assert redirected_to(conn) == "/activate"
|
||||
end
|
||||
|
||||
test "renders captcha errors in case of captcha input verification failure", %{conn: conn} do
|
||||
mock_captcha_failure()
|
||||
|
||||
conn =
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
email: "user@example.com",
|
||||
password: "very-secret",
|
||||
password_confirmation: "very-secret"
|
||||
}
|
||||
)
|
||||
|
||||
assert html_response(conn, 200) =~ "Please complete the captcha"
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /register/invitations/:invitation_id" do
|
||||
@ -121,6 +150,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "registering sends an activation link", %{conn: conn, invitation: invitation} do
|
||||
mock_captcha_success()
|
||||
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
@ -139,6 +170,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
conn: conn,
|
||||
invitation: invitation
|
||||
} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
@ -153,6 +186,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "creates user record", %{conn: conn, invitation: invitation} do
|
||||
mock_captcha_success()
|
||||
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
@ -170,6 +205,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
conn: conn,
|
||||
invitation: invitation
|
||||
} do
|
||||
mock_captcha_success()
|
||||
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
@ -184,6 +221,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "logs the user in", %{conn: conn, invitation: invitation} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
@ -198,6 +237,8 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "user is redirected to activation after registration", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
|
||||
conn =
|
||||
post(conn, "/register",
|
||||
user: %{
|
||||
@ -210,6 +251,25 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
|
||||
assert redirected_to(conn) == "/activate"
|
||||
end
|
||||
|
||||
test "renders captcha errors in case of captcha input verification failure", %{
|
||||
conn: conn,
|
||||
invitation: invitation
|
||||
} do
|
||||
mock_captcha_failure()
|
||||
|
||||
conn =
|
||||
post(conn, "/register/invitation/#{invitation.invitation_id}",
|
||||
user: %{
|
||||
name: "Jane Doe",
|
||||
email: "user@example.com",
|
||||
password: "very-secret",
|
||||
password_confirmation: "very-secret"
|
||||
}
|
||||
)
|
||||
|
||||
assert html_response(conn, 200) =~ "Please complete the captcha"
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /activate" do
|
||||
@ -416,12 +476,21 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
end
|
||||
|
||||
test "email is present and exists - sends password reset email", %{conn: conn} do
|
||||
mock_captcha_success()
|
||||
user = insert(:user)
|
||||
conn = post(conn, "/password/request-reset", %{email: user.email})
|
||||
|
||||
assert html_response(conn, 200) =~ "Success!"
|
||||
assert_email_delivered_with(subject: "Plausible password reset")
|
||||
end
|
||||
|
||||
test "renders captcha errors in case of captcha input verification failure", %{conn: conn} do
|
||||
mock_captcha_failure()
|
||||
user = insert(:user)
|
||||
conn = post(conn, "/password/request-reset", %{email: user.email})
|
||||
|
||||
assert html_response(conn, 200) =~ "Please complete the captcha"
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /password/reset" do
|
||||
@ -690,4 +759,27 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
assert Repo.get(ApiKey, api_key.id)
|
||||
end
|
||||
end
|
||||
|
||||
defp mock_captcha_success() do
|
||||
mock_captcha(true)
|
||||
end
|
||||
|
||||
defp mock_captcha_failure() do
|
||||
mock_captcha(false)
|
||||
end
|
||||
|
||||
defp mock_captcha(success) do
|
||||
expect(
|
||||
Plausible.HTTPClient.Mock,
|
||||
:post,
|
||||
fn _, _, _ ->
|
||||
{:ok,
|
||||
%Finch.Response{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/json"}],
|
||||
body: %{"success" => success}
|
||||
}}
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user