add tests for reviews liveviews and worker
All checks were successful
deploy / deploy (push) Successful in 39s
All checks were successful
deploy / deploy (push) Successful in 39s
- admin reviews test: list, filter, search, moderation (approve/reject/delete) - review form test: rendering, validation, submission, edit flow - review request worker test: email sending, edge cases, scheduling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
244
test/berrypod_web/live/shop/review_form_test.exs
Normal file
244
test/berrypod_web/live/shop/review_form_test.exs
Normal file
@@ -0,0 +1,244 @@
|
||||
defmodule BerrypodWeb.Shop.ReviewFormTest do
|
||||
use BerrypodWeb.ConnCase, async: false
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import Berrypod.AccountsFixtures
|
||||
import Berrypod.ProductsFixtures
|
||||
import Berrypod.OrdersFixtures
|
||||
|
||||
alias Berrypod.Reviews
|
||||
|
||||
setup do
|
||||
user_fixture()
|
||||
{:ok, _} = Berrypod.Settings.set_site_live(true)
|
||||
:ok
|
||||
end
|
||||
|
||||
defp with_email_session(conn, email) do
|
||||
conn
|
||||
|> Phoenix.ConnTest.init_test_session(%{})
|
||||
|> Plug.Conn.put_session("email_session", email)
|
||||
end
|
||||
|
||||
describe "review form with valid token" do
|
||||
setup do
|
||||
prov_conn = provider_connection_fixture(%{provider_type: "printify"})
|
||||
product = product_fixture(%{provider_connection: prov_conn})
|
||||
variant = product_variant_fixture(%{product: product})
|
||||
|
||||
order =
|
||||
order_fixture(%{
|
||||
customer_email: "buyer@example.com",
|
||||
payment_status: "paid",
|
||||
variant_id: variant.id
|
||||
})
|
||||
|
||||
token = Reviews.generate_review_token("buyer@example.com", product.id)
|
||||
|
||||
%{product: product, order: order, token: token}
|
||||
end
|
||||
|
||||
test "renders review form", %{conn: conn, product: product, token: token} do
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
assert html =~ "Write a review"
|
||||
assert html =~ product.title
|
||||
assert html =~ "Rating"
|
||||
assert html =~ "Your name"
|
||||
assert html =~ "Submit review"
|
||||
end
|
||||
|
||||
test "pre-fills author name from order shipping address", %{
|
||||
conn: conn,
|
||||
order: order,
|
||||
token: token
|
||||
} do
|
||||
# Update order with shipping address
|
||||
Berrypod.Orders.update_order(order, %{
|
||||
shipping_address: %{"name" => "Jane Doe", "line1" => "123 Test St"}
|
||||
})
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
assert html =~ "Jane Doe"
|
||||
end
|
||||
|
||||
test "validates rating is required", %{conn: conn, token: token} do
|
||||
{:ok, view, _html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("form", %{"review" => %{"author_name" => "Jane", "rating" => ""}})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "can't be blank" or html =~ "is invalid"
|
||||
end
|
||||
|
||||
test "validates author name is required", %{conn: conn, token: token} do
|
||||
{:ok, view, _html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
# Set rating via event instead of form data (the hidden field only accepts "")
|
||||
render_click(view, "set_rating", %{"rating" => "5"})
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("form", %{"review" => %{"author_name" => ""}})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "can't be blank"
|
||||
end
|
||||
|
||||
test "sets rating via star buttons", %{conn: conn, token: token} do
|
||||
{:ok, view, _html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
# Click on star 4
|
||||
render_click(view, "set_rating", %{"rating" => "4"})
|
||||
|
||||
# The hidden input should have value 4
|
||||
html = render(view)
|
||||
assert html =~ ~r/name="review\[rating\]".*value="4"/s or html =~ "star-filled"
|
||||
end
|
||||
|
||||
test "submits review successfully", %{conn: conn, product: product, token: token} do
|
||||
{:ok, view, _html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
# Set rating first
|
||||
render_click(view, "set_rating", %{"rating" => "5"})
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("form", %{
|
||||
"review" => %{
|
||||
"author_name" => "Jane Doe",
|
||||
"title" => "Great product!",
|
||||
"body" => "Would recommend to everyone."
|
||||
}
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Thanks for your review"
|
||||
assert html =~ "Your review will appear on the product page once it's been approved"
|
||||
|
||||
# Verify review was created
|
||||
review = Reviews.get_review_by_email_and_product("buyer@example.com", product.id)
|
||||
assert review
|
||||
assert review.rating == 5
|
||||
assert review.author_name == "Jane Doe"
|
||||
assert review.title == "Great product!"
|
||||
assert review.status == "pending"
|
||||
end
|
||||
|
||||
test "shows error for already reviewed product", %{conn: conn, product: product, token: token} do
|
||||
# Create existing review first
|
||||
{:ok, _} =
|
||||
Reviews.create_review(%{
|
||||
product_id: product.id,
|
||||
email: "buyer@example.com",
|
||||
author_name: "Jane",
|
||||
rating: 5
|
||||
})
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/new?token=#{token}")
|
||||
|
||||
assert html =~ "already reviewed"
|
||||
assert html =~ "Edit your existing review"
|
||||
end
|
||||
end
|
||||
|
||||
describe "review form with invalid token" do
|
||||
test "shows error for invalid token", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/new?token=invalid_token")
|
||||
|
||||
assert html =~ "expired or is invalid"
|
||||
assert html =~ "Please request a new one"
|
||||
end
|
||||
|
||||
test "shows error when no token provided", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/new")
|
||||
|
||||
assert html =~ "Invalid review link"
|
||||
end
|
||||
end
|
||||
|
||||
describe "edit review" do
|
||||
setup do
|
||||
prov_conn = provider_connection_fixture(%{provider_type: "printify"})
|
||||
product = product_fixture(%{provider_connection: prov_conn})
|
||||
variant = product_variant_fixture(%{product: product})
|
||||
|
||||
_order =
|
||||
order_fixture(%{
|
||||
customer_email: "editor@example.com",
|
||||
payment_status: "paid",
|
||||
variant_id: variant.id
|
||||
})
|
||||
|
||||
{:ok, review} =
|
||||
Reviews.create_review(%{
|
||||
product_id: product.id,
|
||||
email: "editor@example.com",
|
||||
author_name: "Editor",
|
||||
rating: 4,
|
||||
title: "Good product",
|
||||
body: "It works well."
|
||||
})
|
||||
|
||||
{:ok, review} = Reviews.approve_review(review)
|
||||
|
||||
%{product: product, review: review}
|
||||
end
|
||||
|
||||
test "shows edit form with existing values when email session matches", %{
|
||||
conn: conn,
|
||||
product: product,
|
||||
review: review
|
||||
} do
|
||||
conn = with_email_session(conn, "editor@example.com")
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/#{review.id}/edit?product=#{product.slug}")
|
||||
|
||||
assert html =~ "Edit your review"
|
||||
assert html =~ "Editor"
|
||||
assert html =~ "Good product"
|
||||
assert html =~ "It works well"
|
||||
end
|
||||
|
||||
test "shows error when email session doesn't match", %{conn: conn, review: review} do
|
||||
conn = with_email_session(conn, "other@example.com")
|
||||
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/#{review.id}/edit")
|
||||
|
||||
assert html =~ "don't have permission"
|
||||
end
|
||||
|
||||
test "shows error when no email session", %{conn: conn, review: review} do
|
||||
{:ok, _view, html} = live(conn, ~p"/reviews/#{review.id}/edit")
|
||||
|
||||
assert html =~ "don't have permission"
|
||||
end
|
||||
|
||||
test "updates review and resets to pending", %{conn: conn, product: product, review: review} do
|
||||
conn = with_email_session(conn, "editor@example.com")
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/reviews/#{review.id}/edit?product=#{product.slug}")
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("form", %{
|
||||
"review" => %{
|
||||
"title" => "Updated title",
|
||||
"body" => "Updated body"
|
||||
}
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Your updated review will appear once approved"
|
||||
|
||||
# Verify review was updated and status reset
|
||||
updated = Reviews.get_review(review.id)
|
||||
assert updated.title == "Updated title"
|
||||
assert updated.body == "Updated body"
|
||||
assert updated.status == "pending"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user