add review submission flow (phase 3)
All checks were successful
deploy / deploy (push) Successful in 1m10s
All checks were successful
deploy / deploy (push) Successful in 1m10s
- Add ReviewNotifier for verification emails - Add review token generation and verification - Add request_review_verification function - Update reviews_section component with write-a-review form - Create ReviewForm LiveView for submitting/editing reviews - Add /reviews/new and /reviews/:id/edit routes - Add review buttons to order detail page - Update block_types to load real review data - Tests for token and verification functions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -311,11 +311,11 @@ defmodule Berrypod.PagesTest do
|
||||
|
||||
test "loads review data when reviews_section block is present" do
|
||||
blocks = [%{"type" => "reviews_section", "settings" => %{}}]
|
||||
data = Pages.load_block_data(blocks, %{})
|
||||
data = Pages.load_block_data(blocks, %{mode: :preview})
|
||||
|
||||
assert is_list(data.reviews)
|
||||
assert data.average_rating == 5
|
||||
assert data.total_count == 24
|
||||
assert Decimal.equal?(data.average_rating, Decimal.new(5))
|
||||
assert data.review_count == 2
|
||||
end
|
||||
|
||||
test "loads featured products with configurable count" do
|
||||
|
||||
@@ -382,4 +382,73 @@ defmodule Berrypod.ReviewsTest do
|
||||
assert Reviews.get_review(review.id) == nil
|
||||
end
|
||||
end
|
||||
|
||||
# ── Review tokens ────────────────────────────────────────────────────
|
||||
|
||||
describe "generate_review_token/2 and verify_review_token/1" do
|
||||
test "generates and verifies a valid token" do
|
||||
product = product_fixture()
|
||||
email = "buyer@example.com"
|
||||
|
||||
token = Reviews.generate_review_token(email, product.id)
|
||||
assert is_binary(token)
|
||||
|
||||
{:ok, result} = Reviews.verify_review_token(token)
|
||||
assert result.email == email
|
||||
assert result.product_id == product.id
|
||||
end
|
||||
|
||||
test "normalises email to lowercase" do
|
||||
product = product_fixture()
|
||||
token = Reviews.generate_review_token("BUYER@EXAMPLE.COM", product.id)
|
||||
|
||||
{:ok, result} = Reviews.verify_review_token(token)
|
||||
assert result.email == "buyer@example.com"
|
||||
end
|
||||
|
||||
test "rejects invalid tokens" do
|
||||
assert {:error, :invalid} = Reviews.verify_review_token("invalid_token")
|
||||
end
|
||||
end
|
||||
|
||||
describe "request_review_verification/3" do
|
||||
test "returns error when email has not purchased product" do
|
||||
product = product_fixture()
|
||||
|
||||
result =
|
||||
Reviews.request_review_verification("nobody@example.com", product.id, product.title)
|
||||
|
||||
assert {:error, :no_purchase} = result
|
||||
end
|
||||
|
||||
test "returns error when user has already reviewed" do
|
||||
product = product_fixture()
|
||||
|
||||
{:ok, _} =
|
||||
Reviews.create_review(%{
|
||||
product_id: product.id,
|
||||
email: "buyer@example.com",
|
||||
author_name: "Jane",
|
||||
rating: 5
|
||||
})
|
||||
|
||||
result = Reviews.request_review_verification("buyer@example.com", product.id, product.title)
|
||||
assert {:error, :already_reviewed} = result
|
||||
end
|
||||
|
||||
test "sends verification email when user has purchased" do
|
||||
conn = provider_connection_fixture(%{provider_type: "printify"})
|
||||
product = product_fixture(%{provider_connection: conn})
|
||||
variant = product_variant_fixture(%{product: product})
|
||||
|
||||
order_fixture(%{
|
||||
customer_email: "buyer@example.com",
|
||||
payment_status: "paid",
|
||||
variant_id: variant.id
|
||||
})
|
||||
|
||||
result = Reviews.request_review_verification("buyer@example.com", product.id, product.title)
|
||||
assert {:ok, :sent} = result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user