-module(logic_review_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). -define(TABLES, [user, admin, calendar, event, booking, review, review_vote]). setup() -> eh_test_support:start_mnesia(), eh_test_support:ensure_tables(?TABLES), ok. cleanup(_) -> eh_test_support:delete_tables(?TABLES), eh_test_support:stop_mnesia(), 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 calendar without booking", fun test_cannot_review_calendar_without_booking/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() -> UserId = base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}), User = eh_test_support:make_user(#{id => UserId, email => <>}), mnesia:dirty_write(User), UserId. create_test_admin() -> AdminId = base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}), Admin = eh_test_support:seed_admin(#{id => AdminId, email => <>}), Admin#admin.id. 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">>, eh_test_support:future_start(), 60), Event#event.id. create_booking(UserId, EventId) -> {ok, Booking} = core_booking:create(EventId, UserId, pending), Now = calendar:universal_time(), {ok, _} = core_booking:update(Booking#booking.id, [{status, confirmed}, {confirmed_at, Now}]), Booking#booking.id. test_create_event_review() -> OwnerId = create_test_user(), ParticipantId = create_test_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(), ReviewerId = create_test_user(), CalendarId = create_test_calendar(OwnerId), EventId = create_test_event(CalendarId), create_booking(ReviewerId, EventId), {ok, Review} = logic_review:create_review(ReviewerId, calendar, CalendarId, 4, <<"Nice">>), ?assertEqual(4, Review#review.rating). test_cannot_review_calendar_without_booking() -> OwnerId = create_test_user(), UserId = create_test_user(), CalendarId = create_test_calendar(OwnerId), _EventId = create_test_event(CalendarId), {error, cannot_review} = logic_review:create_review(UserId, calendar, CalendarId, 4, <<"Nope">>). test_cannot_review_without_booking() -> OwnerId = create_test_user(), UserId = create_test_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(), ParticipantId = create_test_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(), ParticipantId = create_test_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(), ParticipantId = create_test_user(), OtherId = create_test_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(), ParticipantId = create_test_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(), ParticipantId = create_test_user(), AdminId = create_test_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(), P1 = create_test_user(), P2 = create_test_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).