199 lines
7.7 KiB
Erlang
199 lines
7.7 KiB
Erlang
-module(stats_tops_tests).
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
-include("records.hrl").
|
|
|
|
-define(TABLES, [event, calendar, review, report, stats_counter, stats_daily]).
|
|
|
|
setup() ->
|
|
eh_test_support:start_mnesia(),
|
|
eh_test_support:ensure_tables(?TABLES),
|
|
{ok, _} = stats_collector:start_link(),
|
|
ok = stats_collector:subscribe(),
|
|
ok.
|
|
|
|
cleanup(_) ->
|
|
case whereis(stats_collector) of
|
|
undefined -> ok;
|
|
Pid ->
|
|
unlink(Pid),
|
|
exit(Pid, kill),
|
|
wait_dead(Pid, 50)
|
|
end,
|
|
eh_test_support:delete_tables(?TABLES),
|
|
eh_test_support:stop_mnesia(),
|
|
ok.
|
|
|
|
wait_dead(_Pid, 0) -> ok;
|
|
wait_dead(Pid, N) ->
|
|
case is_process_alive(Pid) of
|
|
true -> timer:sleep(20), wait_dead(Pid, N - 1);
|
|
false -> ok
|
|
end.
|
|
|
|
stats_tops_test_() ->
|
|
{foreach, fun setup/0, fun cleanup/1, [
|
|
{"top events by rating order", fun test_event_rating_top/0},
|
|
{"top calendars by rating and reviews", fun test_calendar_tops/0},
|
|
{"rating update reorders top", fun test_rating_update/0},
|
|
{"review target tops all/pos/neg", fun test_review_target_tops/0},
|
|
{"report target tops", fun test_report_target_tops/0},
|
|
{"calendar pos/neg from reviews", fun test_calendar_pos_neg/0}
|
|
]}.
|
|
|
|
test_event_rating_top() ->
|
|
Now = calendar:universal_time(),
|
|
ok = mnesia:dirty_write(make_event(<<"e_low">>, 2.0, Now)),
|
|
ok = mnesia:dirty_write(make_event(<<"e_high">>, 5.0, Now)),
|
|
ok = mnesia:dirty_write(make_event(<<"e_mid">>, 3.5, Now)),
|
|
wait_top_event(<<"e_high">>, 30),
|
|
Top = core_event:get_top_events_by_rating(2),
|
|
Ids = [E#event.id || E <- Top],
|
|
?assertEqual([<<"e_high">>, <<"e_mid">>], Ids).
|
|
|
|
test_calendar_tops() ->
|
|
Now = calendar:universal_time(),
|
|
ok = mnesia:dirty_write(make_calendar(<<"c1">>, 4.0, 10, Now)),
|
|
ok = mnesia:dirty_write(make_calendar(<<"c2">>, 5.0, 2, Now)),
|
|
ok = mnesia:dirty_write(make_calendar(<<"c3">>, 3.0, 20, Now)),
|
|
wait_top_cal_rating(<<"c2">>, 30),
|
|
ByRating = [C#calendar.id || C <- core_calendar:get_top_calendars_by_rating(2)],
|
|
?assertEqual([<<"c2">>, <<"c1">>], ByRating),
|
|
ByReviews = [C#calendar.id || C <- core_calendar:get_top_calendars_by_reviews(2)],
|
|
?assertEqual([<<"c3">>, <<"c1">>], ByReviews).
|
|
|
|
test_rating_update() ->
|
|
Now = calendar:universal_time(),
|
|
E1 = make_event(<<"eu1">>, 4.0, Now),
|
|
E2 = make_event(<<"eu2">>, 3.0, Now),
|
|
ok = mnesia:dirty_write(E1),
|
|
ok = mnesia:dirty_write(E2),
|
|
wait_top_event(<<"eu1">>, 30),
|
|
ok = mnesia:dirty_write(E2#event{rating_avg = 4.5}),
|
|
wait_top_event(<<"eu2">>, 30),
|
|
Top = core_event:get_top_events_by_rating(1),
|
|
?assertEqual([<<"eu2">>], [E#event.id || E <- Top]).
|
|
|
|
test_review_target_tops() ->
|
|
Now = calendar:universal_time(),
|
|
ok = mnesia:dirty_write(make_review(<<"r1">>, calendar, <<"cA">>, 5, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"r2">>, calendar, <<"cA">>, 5, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"r3">>, event, <<"eA">>, 1, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"r4">>, calendar, <<"cB">>, 2, Now)),
|
|
wait_review_top({calendar, <<"cA">>}, 30),
|
|
All = core_review:get_top_targets_by_reviews(3),
|
|
?assertMatch([{calendar, <<"cA">>, 2} | _], All),
|
|
AllKeys = [{T, I} || {T, I, _} <- All],
|
|
?assert(lists:member({event, <<"eA">>}, AllKeys)),
|
|
?assert(lists:member({calendar, <<"cB">>}, AllKeys)),
|
|
Pos = core_review:get_top_targets_by_positive_reviews(1),
|
|
?assertEqual([{calendar, <<"cA">>, 2}], Pos),
|
|
Neg = core_review:get_top_targets_by_negative_reviews(2),
|
|
NegIds = [{T, I} || {T, I, _} <- Neg],
|
|
?assert(lists:member({event, <<"eA">>}, NegIds)),
|
|
?assert(lists:member({calendar, <<"cB">>}, NegIds)).
|
|
|
|
test_report_target_tops() ->
|
|
Now = calendar:universal_time(),
|
|
ok = mnesia:dirty_write(make_report(<<"p1">>, calendar, <<"cX">>, Now)),
|
|
ok = mnesia:dirty_write(make_report(<<"p2">>, calendar, <<"cX">>, Now)),
|
|
ok = mnesia:dirty_write(make_report(<<"p3">>, event, <<"eX">>, Now)),
|
|
wait_report_top({calendar, <<"cX">>}, 30),
|
|
Top = core_report:get_top_targets_by_reports(2),
|
|
?assertEqual([{calendar, <<"cX">>, 2}, {event, <<"eX">>, 1}], Top).
|
|
|
|
test_calendar_pos_neg() ->
|
|
Now = calendar:universal_time(),
|
|
ok = mnesia:dirty_write(make_calendar(<<"cp1">>, 0.0, 0, Now)),
|
|
ok = mnesia:dirty_write(make_calendar(<<"cp2">>, 0.0, 0, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"rp1">>, calendar, <<"cp1">>, 5, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"rp2">>, calendar, <<"cp1">>, 4, Now)),
|
|
ok = mnesia:dirty_write(make_review(<<"rn1">>, calendar, <<"cp2">>, 1, Now)),
|
|
wait_cal_pos(<<"cp1">>, 30),
|
|
Pos = [C#calendar.id || C <- core_calendar:get_top_calendars_by_positive_reviews(1)],
|
|
?assertEqual([<<"cp1">>], Pos),
|
|
Neg = [C#calendar.id || C <- core_calendar:get_top_calendars_by_negative_reviews(1)],
|
|
?assertEqual([<<"cp2">>], Neg).
|
|
|
|
make_review(Id, Type, TargetId, Rating, Now) ->
|
|
#review{
|
|
id = Id, user_id = <<"u1">>, target_type = Type, target_id = TargetId,
|
|
rating = Rating, comment = <<>>, status = visible, reason = <<>>,
|
|
likes = 0, dislikes = 0, created_at = Now, updated_at = Now
|
|
}.
|
|
|
|
make_report(Id, Type, TargetId, Now) ->
|
|
#report{
|
|
id = Id, reporter_id = <<"u1">>, target_type = Type, target_id = TargetId,
|
|
reason = <<"spam">>, status = pending, created_at = Now,
|
|
resolved_at = undefined, resolved_by = <<>>
|
|
}.
|
|
|
|
make_event(Id, Avg, Now) ->
|
|
#event{
|
|
id = Id, calendar_id = <<"cal">>, title = Id, description = <<>>,
|
|
event_type = single, start_time = Now, duration = 60,
|
|
recurrence_rule = <<>>, master_id = <<>>, is_instance = false,
|
|
specialist_id = <<>>, location = undefined, tags = [],
|
|
capacity = 10, online_link = <<>>, status = active, reason = <<>>,
|
|
rating_avg = Avg, rating_count = 1, attachments = [], edit_history = [],
|
|
created_at = Now, updated_at = Now
|
|
}.
|
|
|
|
make_calendar(Id, Avg, Count, Now) ->
|
|
#calendar{
|
|
id = Id, owner_id = <<"u1">>, title = Id, description = <<>>,
|
|
short_name = Id, category = <<>>, color = <<>>, image_url = <<>>,
|
|
settings = #{}, tags = [], type = personal, confirmation = auto,
|
|
rating_avg = Avg, rating_count = Count, status = active, reason = <<>>,
|
|
created_at = Now, updated_at = Now
|
|
}.
|
|
|
|
wait_top_event(ExpectedId, 0) ->
|
|
Top = core_event:get_top_events_by_rating(1),
|
|
?assertEqual([ExpectedId], [E#event.id || E <- Top]);
|
|
wait_top_event(ExpectedId, N) ->
|
|
case core_event:get_top_events_by_rating(1) of
|
|
[#event{id = ExpectedId}] -> ok;
|
|
_ -> timer:sleep(25), wait_top_event(ExpectedId, N - 1)
|
|
end.
|
|
|
|
wait_top_cal_rating(ExpectedId, 0) ->
|
|
Top = core_calendar:get_top_calendars_by_rating(1),
|
|
?assertEqual([ExpectedId], [C#calendar.id || C <- Top]);
|
|
wait_top_cal_rating(ExpectedId, N) ->
|
|
case core_calendar:get_top_calendars_by_rating(1) of
|
|
[#calendar{id = ExpectedId}] -> ok;
|
|
_ -> timer:sleep(25), wait_top_cal_rating(ExpectedId, N - 1)
|
|
end.
|
|
|
|
wait_review_top(Expected, 0) ->
|
|
case core_review:get_top_targets_by_reviews(1) of
|
|
[{T, I, _} | _] -> ?assertEqual(Expected, {T, I});
|
|
Other -> ?assertEqual(Expected, Other)
|
|
end;
|
|
wait_review_top(Expected = {T, I}, N) ->
|
|
case core_review:get_top_targets_by_reviews(1) of
|
|
[{T, I, _} | _] -> ok;
|
|
_ -> timer:sleep(25), wait_review_top(Expected, N - 1)
|
|
end.
|
|
|
|
wait_report_top(Expected, 0) ->
|
|
case core_report:get_top_targets_by_reports(1) of
|
|
[{T, I, _} | _] -> ?assertEqual(Expected, {T, I});
|
|
Other -> ?assertEqual(Expected, Other)
|
|
end;
|
|
wait_report_top(Expected = {T, I}, N) ->
|
|
case core_report:get_top_targets_by_reports(1) of
|
|
[{T, I, _} | _] -> ok;
|
|
_ -> timer:sleep(25), wait_report_top(Expected, N - 1)
|
|
end.
|
|
|
|
wait_cal_pos(ExpectedId, 0) ->
|
|
Top = core_calendar:get_top_calendars_by_positive_reviews(1),
|
|
?assertEqual([ExpectedId], [C#calendar.id || C <- Top]);
|
|
wait_cal_pos(ExpectedId, N) ->
|
|
case core_calendar:get_top_calendars_by_positive_reviews(1) of
|
|
[#calendar{id = ExpectedId}] -> ok;
|
|
_ -> timer:sleep(25), wait_cal_pos(ExpectedId, N - 1)
|
|
end.
|