-module(logic_review_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). setup() -> mnesia:start(), mnesia:create_table(user, [{attributes, record_info(fields, user)}, {ram_copies, [node()]}]), mnesia:create_table(calendar, [{attributes, record_info(fields, calendar)}, {ram_copies, [node()]}]), mnesia:create_table(event, [{attributes, record_info(fields, event)}, {ram_copies, [node()]}]), mnesia:create_table(booking, [{attributes, record_info(fields, booking)}, {ram_copies, [node()]}]), mnesia:create_table(review, [{attributes, record_info(fields, review)}, {ram_copies, [node()]}]), ok. cleanup(_) -> mnesia:delete_table(review), mnesia:delete_table(booking), mnesia:delete_table(event), mnesia:delete_table(calendar), mnesia:delete_table(user), mnesia:stop(), ok. logic_review_test_() -> {foreach, fun setup/0, fun cleanup/1, [ {"Create review for event", fun test_create_event_review/0}, {"Create review for calendar", fun test_create_calendar_review/0}, {"Cannot review without booking", fun test_cannot_review_without_booking/0}, {"Cannot review twice", fun test_cannot_review_twice/0}, {"Update own review", fun test_update_own_review/0}, {"Cannot update others review", fun test_cannot_update_others/0}, {"Delete own review", fun test_delete_own_review/0}, {"Admin can hide review", fun test_admin_hide_review/0}, {"Rating updates target", fun test_rating_updates_target/0} ]}. create_test_user(Role) -> UserId = base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}), User = #user{id = UserId, email = <>, password_hash = <<"hash">>, role = Role, status = active, created_at = calendar:universal_time(), updated_at = calendar:universal_time()}, mnesia:dirty_write(User), UserId. create_test_calendar(OwnerId) -> {ok, Calendar} = core_calendar:create(OwnerId, <<"Test">>, <<"">>, manual), Calendar#calendar.id. create_test_event(CalendarId) -> {ok, Event} = core_event:create(CalendarId, <<"Event">>, {{2026, 6, 1}, {10, 0, 0}}, 60), Event#event.id. create_booking(UserId, EventId) -> {ok, Booking} = core_booking:create(EventId, UserId), core_booking:update_status(Booking#booking.id, confirmed), Booking#booking.id. test_create_event_review() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, Review} = logic_review:create_review(ParticipantId, event, EventId, 5, <<"Great!">>), ?assertEqual(5, Review#review.rating), % Проверяем, что рейтинг события обновился {ok, Event} = core_event:get_by_id(EventId), ?assertEqual(5.0, Event#event.rating_avg), ?assertEqual(1, Event#event.rating_count). test_create_calendar_review() -> OwnerId = create_test_user(user), ReviewerId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), {ok, Review} = logic_review:create_review(ReviewerId, calendar, CalendarId, 4, <<"Nice">>), ?assertEqual(4, Review#review.rating). test_cannot_review_without_booking() -> OwnerId = create_test_user(user), UserId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), {error, cannot_review} = logic_review:create_review(UserId, event, EventId, 5, <<"">>). test_cannot_review_twice() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, _} = logic_review:create_review(ParticipantId, event, EventId, 5, <<"">>), {error, already_reviewed} = logic_review:create_review(ParticipantId, event, EventId, 4, <<"">>). test_update_own_review() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, Review} = logic_review:create_review(ParticipantId, event, EventId, 3, <<"">>), {ok, Updated} = logic_review:update_review(ParticipantId, Review#review.id, [{rating, 5}]), ?assertEqual(5, Updated#review.rating). test_cannot_update_others() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), OtherId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, Review} = logic_review:create_review(ParticipantId, event, EventId, 3, <<"">>), {error, access_denied} = logic_review:update_review(OtherId, Review#review.id, [{rating, 5}]). test_delete_own_review() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, Review} = logic_review:create_review(ParticipantId, event, EventId, 3, <<"">>), {ok, deleted} = logic_review:delete_review(ParticipantId, Review#review.id). test_admin_hide_review() -> OwnerId = create_test_user(user), ParticipantId = create_test_user(user), AdminId = create_test_user(admin), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ParticipantId, EventId), {ok, Review} = logic_review:create_review(ParticipantId, event, EventId, 3, <<"Bad">>), {ok, Hidden} = logic_review:hide_review(AdminId, Review#review.id), ?assertEqual(hidden, Hidden#review.status). test_rating_updates_target() -> OwnerId = create_test_user(user), P1 = create_test_user(user), P2 = create_test_user(user), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(P1, EventId), create_booking(P2, EventId), {ok, _} = logic_review:create_review(P1, event, EventId, 5, <<"">>), {ok, Event1} = core_event:get_by_id(EventId), ?assertEqual(5.0, Event1#event.rating_avg), ?assertEqual(1, Event1#event.rating_count), {ok, _} = logic_review:create_review(P2, event, EventId, 3, <<"">>), {ok, Event2} = core_event:get_by_id(EventId), ?assertEqual(4.0, Event2#event.rating_avg), ?assertEqual(2, Event2#event.rating_count).