wie kann ich einstellen, dass session-setup, wenn ich test-phoenix-Aktion, die brauchen user_id in der session?
Habe ich eine Prüfung, die müssen user_id Sitzung vor der Prüfung, weil diese Aktion kennen müssen, um current_user.
setup do
%User{
id: 123456,
username: "lcp",
email: "[email protected]",
password: Comeonin.Bcrypt.hashpwsalt("password")
} |> Repo.insert
{:ok, user: Repo.get(User, 123456) }
end
test "POST /posts", context do
# conn = conn()
# |> put_session(:user_id, context[:user].id)
# |> post("/posts", %{ post: %{ title: "title", body: "body" } })
# assert get_flash(conn, :info) == "Post created successfully."
# updated to =>
conn = conn()
|> Map.put(:secret_key_base, String.duplicate("abcdefgh", 8))
|> Plug.Session.call(@session)
|> Plug.Conn.fetch_session
|> put_session(:user_id, context[:user].id)
|> post("/posts", %{ post: %{ title: "title", body: "body" } })
assert get_flash(conn, :info) == "Post created successfully."
end
Ich versuchte diesen code, aber es sagt, dass session not fetched, call fetch_session/2
.
web/Controller/controller_helper.ex
defmodule SimpleBlog.ControllerHelpers do
alias Phoenix.Controller
alias Plug.Conn
alias SimpleBlog.Router.Helpers
def authenticate(conn, _) do
case Conn.get_session(conn, :user_id) do
nil ->
unauthorized(conn)
user_id ->
case SimpleBlog.Repo.get(SimpleBlog.User, user_id) do
{:ok, user} ->
Conn.assign(conn, :current_user, user)
nil ->
unauthorized(conn)
end
end
end
def unauthorized(conn) do
conn
|> Controller.put_flash(:error, "You must be logged in")
|> Controller.redirect(to: Helpers.session_path(conn, :new))
|> Conn.halt
end
end
Aktualisiert
Bekomme ich null, wenn ich user_id aus der session durch Conn.get_session(conn, :user_id)
.
Hier ist die post controller
web/Controller/post_controller.ex
defmodule SimpleBlog.PostController do
use SimpleBlog.Web, :controller
import SimpleBlog.ControllerHelpers
alias SimpleBlog.Post
plug :authenticate when not action in [:new]
def create(conn, %{ "post" => post_params }) do
changeset = Post.changeset(%Post{}, post_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Post created successfully.")
|> redirect(to: post_path(conn, :new))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
end
Es ist meine test-Datei.
defmodule SimpleBlog.PostControllerTest do
use SimpleBlog.ConnCase
alias SimpleBlog.Repo
alias SimpleBlog.User
@session Plug.Session.init(
store: :cookie,
key: "_app",
encryption_salt: "yadayada",
signing_salt: "yadayada"
)
setup do
%User{
id: 123456,
username: "lcp",
email: "[email protected]",
password: Comeonin.Bcrypt.hashpwsalt("password")
} |> Repo.insert
{:ok, user: Repo.get(User, 123456) }
end
@tag timeout: 900000
test "POST /posts", context do
conn = conn()
|> Map.put(:secret_key_base, String.duplicate("abcdefgh", 8))
|> Plug.Session.call(@session)
|> Plug.Conn.fetch_session
|> put_session(:user_id, context[:user].id)
|> post("/posts", %{ post: %{ title: "title", body: "body" } })
assert get_flash(conn, :info) == "Post created successfully."
end
end
update ..
lib/simple_blog/Stecker/authentifiziert.ex
Definiere ich ein Plugin authentifiziert
defmodule SimpleBlog.Plugs.Authenticated do
import Plug.Conn
alias Phoenix.Controller
alias SimpleBlog.Router.Helpers
alias SimpleBlog.User
def init(options) do
options
end
def call(conn, _) do
case conn |> current_user_id do
nil ->
conn
|> Controller.put_flash(:error, "You must be logged in")
|> Controller.redirect(to: Helpers.session_path(conn, :new))
|> halt
current_user_id ->
conn |> assign(:current_user, SimpleBlog.Repo.get(User, current_user_id))
end
end
defp current_user_id(conn) do
case Mix.env do
:test ->
conn.private[:authenticated_current_user_id]
_ ->
conn |> fetch_session |> get_session(:current_user_id)
end
end
end
in meinem test
conn = conn()
|> put_private(:authenticated_current_user_id, context[:user].id)
|> post("/posts", %{ post: %{ title: "title", body: "body" } })
assert get_flash(conn, :info) == "Post created successfully."
nun, der test ist bestanden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie eigentlich nicht tun können, wie dies aufgrund der
post
Aktion das zurücksetzen der session. Haben Sie ein paar Optionen.Ersten, die Sie tun können, ein integration test Besuche, die Ihre login-Pfad mit gültigen Anmeldedaten, und stellen Sie dann Ihre Anforderung zum erstellen des post.
Zweitens, erstellen Sie eine Authentifizierungs-plug wie diese:
Sie können dies testen, indem Sie etwas wie das folgende stammt aus der Phoenix tests:
Nun können Sie testen Sie Ihre controller by doing:
Plug.Conn.get_session(conn, :user_id)
fetch_session
zum einrichten der Sitzung und dann eine Anfrage mit, dass die session-Wert - Anforderung setzt die Sitzung. Ihre Optionen sind entweder eine vollständige integration test (rufen Sie Ihren sign_in route in der test-first-einrichten der Sitzung) oder umgestalten, es heraus zu Holen ausconn.assigns
oder die Sitzungassign(:current_user, user)
hat den trick; gab es keine Notwendigkeit, um in der session-config für mich.current_user
in meinem Authentifizierungs-plug hat eineconn.assigns[:current_user] || get_session(conn, :current_user)
Linie wirklich nur um bessere Tests. Ich weiß nicht, ob das gut oder schlecht ist, aber in jedem Fall: kommt zu denken es, (träge) zuweisen esassigns
wie Sie vorgeschlagen scheint cleaner.Eine weitere einfache Möglichkeit ist die Verwendung
assigns
und träge laden der Daten aus der session. Während der Integrationstests werden die Daten aus der session geladen wird, aber während der unit-Tests können Sie einfach die Daten zuzuordnen:Kredit geht an @Karpfen aus den Kommentaren, ich dachte nur das es verdient, gepostet als Antwort.