feat: upsert stats counters, daily buckets and ETS tops for admin metrics. Refs EventHub/EventHubBack#42 #43 #44 #45 #46
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
-module(core_admin_stats_index_tests).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("records.hrl").
|
||||
|
||||
-define(TABLES, [report, ticket, user]).
|
||||
-define(ADMIN_A, <<"adm_a">>).
|
||||
-define(ADMIN_B, <<"adm_b">>).
|
||||
|
||||
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.
|
||||
|
||||
admin_stats_index_test_() ->
|
||||
{foreach, fun setup/0, fun cleanup/1, [
|
||||
{"reports resolved_by index filters by admin", fun test_reports_by_admin/0},
|
||||
{"tickets assigned_to index filters by admin", fun test_tickets_by_admin/0}
|
||||
]}.
|
||||
|
||||
test_reports_by_admin() ->
|
||||
Now = calendar:universal_time(),
|
||||
ok = mnesia:dirty_write(#report{
|
||||
id = <<"r1">>, reporter_id = <<"u1">>, target_type = calendar,
|
||||
target_id = <<"c1">>, reason = <<"spam">>, status = reviewed,
|
||||
created_at = Now, resolved_at = Now, resolved_by = ?ADMIN_A
|
||||
}),
|
||||
ok = mnesia:dirty_write(#report{
|
||||
id = <<"r2">>, reporter_id = <<"u1">>, target_type = calendar,
|
||||
target_id = <<"c2">>, reason = <<"spam">>, status = reviewed,
|
||||
created_at = Now, resolved_at = Now, resolved_by = ?ADMIN_B
|
||||
}),
|
||||
ok = mnesia:dirty_write(#report{
|
||||
id = <<"r3">>, reporter_id = <<"u1">>, target_type = event,
|
||||
target_id = <<"e1">>, reason = <<"spam">>, status = dismissed,
|
||||
created_at = Now, resolved_at = Now, resolved_by = ?ADMIN_A
|
||||
}),
|
||||
?assertEqual(1, core_report:count_reports_resolved_by_admin(?ADMIN_A, reviewed)),
|
||||
?assertEqual(1, core_report:count_reports_resolved_by_admin(?ADMIN_A, dismissed)),
|
||||
?assertEqual(1, core_report:count_reports_resolved_by_admin(?ADMIN_B, reviewed)),
|
||||
?assertEqual(0, core_report:count_reports_resolved_by_admin(?ADMIN_B, dismissed)).
|
||||
|
||||
test_tickets_by_admin() ->
|
||||
Now = calendar:universal_time(),
|
||||
ok = mnesia:dirty_write(#ticket{
|
||||
id = <<"t1">>, reporter_id = <<"u1">>, error_hash = <<"h1">>,
|
||||
error_message = <<"e">>, stacktrace = <<>>, context = <<>>,
|
||||
count = 1, first_seen = Now, last_seen = Now, status = open,
|
||||
assigned_to = ?ADMIN_A, resolution_note = <<>>, closed_at = undefined,
|
||||
source = <<"backend">>
|
||||
}),
|
||||
ok = mnesia:dirty_write(#ticket{
|
||||
id = <<"t2">>, reporter_id = <<"u1">>, error_hash = <<"h2">>,
|
||||
error_message = <<"e">>, stacktrace = <<>>, context = <<>>,
|
||||
count = 1, first_seen = Now, last_seen = Now, status = resolved,
|
||||
assigned_to = ?ADMIN_A, resolution_note = <<>>, closed_at = Now,
|
||||
source = <<"backend">>
|
||||
}),
|
||||
ok = mnesia:dirty_write(#ticket{
|
||||
id = <<"t3">>, reporter_id = <<"u1">>, error_hash = <<"h3">>,
|
||||
error_message = <<"e">>, stacktrace = <<>>, context = <<>>,
|
||||
count = 1, first_seen = Now, last_seen = Now, status = open,
|
||||
assigned_to = ?ADMIN_B, resolution_note = <<>>, closed_at = undefined,
|
||||
source = <<"backend">>
|
||||
}),
|
||||
?assertEqual(2, core_ticket:count_tickets_by_admin(?ADMIN_A, all)),
|
||||
?assertEqual(1, core_ticket:count_tickets_by_admin(?ADMIN_A, open)),
|
||||
?assertEqual(1, core_ticket:count_tickets_by_admin(?ADMIN_A, resolved)),
|
||||
?assertEqual(1, core_ticket:count_tickets_by_admin(?ADMIN_B, all)).
|
||||
@@ -72,8 +72,27 @@ stop_mnesia() ->
|
||||
|
||||
ensure_tables(Tables) when is_list(Tables) ->
|
||||
lists:foreach(fun ensure_table/1, Tables),
|
||||
maybe_add_admin_stats_indexes(Tables),
|
||||
ok.
|
||||
|
||||
maybe_add_admin_stats_indexes(Tables) ->
|
||||
case lists:member(report, Tables) of
|
||||
true -> add_index(report, resolved_by);
|
||||
false -> ok
|
||||
end,
|
||||
case lists:member(ticket, Tables) of
|
||||
true -> add_index(ticket, assigned_to);
|
||||
false -> ok
|
||||
end.
|
||||
|
||||
add_index(Table, Attr) ->
|
||||
case catch mnesia:add_table_index(Table, Attr) of
|
||||
{atomic, ok} -> ok;
|
||||
{aborted, {already_exists, _}} -> ok;
|
||||
{aborted, {already_exists, _, _}} -> ok;
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
ensure_table(Table) ->
|
||||
case lists:member(Table, mnesia:system_info(tables)) of
|
||||
true ->
|
||||
@@ -133,8 +152,10 @@ table_opts(admin_audit) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, admin_audit)}];
|
||||
table_opts(notification) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, notification)}];
|
||||
table_opts(stats) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, stats)}];
|
||||
table_opts(stats_counter) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, stats_counter)}];
|
||||
table_opts(stats_daily) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, stats_daily)}];
|
||||
table_opts(session) ->
|
||||
[{ram_copies, [node()]}, {attributes, record_info(fields, session)}];
|
||||
table_opts(verification) ->
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
-module(stats_collector_tests).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("records.hrl").
|
||||
|
||||
-define(TABLES, [user, event, calendar, booking, review, report, ticket,
|
||||
subscription, 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_collector_test_() ->
|
||||
{foreach, fun setup/0, fun cleanup/1, [
|
||||
{"backfill from existing rows", fun test_backfill/0},
|
||||
{"live write updates dims and daily", fun test_live_write/0},
|
||||
{"status transition moves counters", fun test_status_move/0},
|
||||
{"core_stats reads via collector", fun test_core_stats_api/0},
|
||||
{"ticket avg resolution from counters", fun test_ticket_avg_resolution/0},
|
||||
{"report avg resolution from counters", fun test_report_avg_resolution/0}
|
||||
]}.
|
||||
|
||||
test_backfill() ->
|
||||
Now = calendar:universal_time(),
|
||||
ok = mnesia:dirty_write(eh_test_support:make_user(#{
|
||||
id => <<"u1">>, status => pending, role => user, created_at => Now
|
||||
})),
|
||||
ok = mnesia:dirty_write(eh_test_support:make_user(#{
|
||||
id => <<"u2">>, status => active, role => user, created_at => Now
|
||||
})),
|
||||
ok = stats_collector:rebuild(),
|
||||
?assertEqual(1, core_stats:with_counter({user_by_status, pending}, fun() -> -1 end)),
|
||||
?assertEqual(1, core_stats:with_counter({user_by_status, active}, fun() -> -1 end)),
|
||||
{Date, _} = Now,
|
||||
From = {Date, {0, 0, 0}},
|
||||
To = {Date, {23, 59, 59}},
|
||||
Daily = core_stats:with_daily(users_created, From, To, fun() -> [] end),
|
||||
?assertEqual([{Date, 2}], Daily).
|
||||
|
||||
test_live_write() ->
|
||||
Now = calendar:universal_time(),
|
||||
ok = mnesia:dirty_write(eh_test_support:make_user(#{
|
||||
id => <<"live1">>, status => active, created_at => Now
|
||||
})),
|
||||
wait_counter({user_by_status, active}, 1, 20),
|
||||
?assertEqual(1, core_stats:with_counter({user_by_status, active}, fun() -> 0 end)).
|
||||
|
||||
test_status_move() ->
|
||||
Now = calendar:universal_time(),
|
||||
User = eh_test_support:make_user(#{
|
||||
id => <<"move1">>, status => pending, created_at => Now
|
||||
}),
|
||||
ok = mnesia:dirty_write(User),
|
||||
wait_counter({user_by_status, pending}, 1, 20),
|
||||
ok = mnesia:dirty_write(User#user{status = active}),
|
||||
wait_counter({user_by_status, pending}, 0, 20),
|
||||
wait_counter({user_by_status, active}, 1, 20),
|
||||
?assertEqual(0, core_stats:with_counter({user_by_status, pending}, fun() -> -1 end)),
|
||||
?assertEqual(1, core_stats:with_counter({user_by_status, active}, fun() -> -1 end)).
|
||||
|
||||
test_core_stats_api() ->
|
||||
?assert(core_stats:available()),
|
||||
Now = calendar:universal_time(),
|
||||
ok = mnesia:dirty_write(#report{
|
||||
id = <<"r1">>,
|
||||
reporter_id = <<"u1">>,
|
||||
target_type = calendar,
|
||||
target_id = <<"c1">>,
|
||||
reason = <<"spam">>,
|
||||
status = pending,
|
||||
created_at = Now,
|
||||
resolved_at = undefined,
|
||||
resolved_by = <<>>
|
||||
}),
|
||||
wait_counter({report_by_status, pending}, 1, 20),
|
||||
{ok, Dim} = core_stats:get_dim(report, status),
|
||||
?assertEqual(1, proplists:get_value(pending, Dim, 0)).
|
||||
|
||||
test_ticket_avg_resolution() ->
|
||||
First = {{2026, 1, 1}, {0, 0, 0}},
|
||||
Closed = {{2026, 1, 1}, {2, 0, 0}}, %% 2 hours
|
||||
ok = mnesia:dirty_write(#ticket{
|
||||
id = <<"t_avg">>, reporter_id = <<"u1">>, error_hash = <<"h">>,
|
||||
error_message = <<"e">>, stacktrace = <<>>, context = <<>>,
|
||||
count = 1, first_seen = First, last_seen = Closed, status = closed,
|
||||
assigned_to = <<>>, resolution_note = <<>>, closed_at = Closed,
|
||||
source = <<"backend">>
|
||||
}),
|
||||
wait_counter(ticket_resolved_count, 1, 20),
|
||||
Avg = core_ticket:avg_resolution_time(),
|
||||
?assertEqual(2.0, Avg).
|
||||
|
||||
test_report_avg_resolution() ->
|
||||
Created = {{2026, 1, 1}, {0, 0, 0}},
|
||||
Resolved = {{2026, 1, 1}, {3, 0, 0}}, %% 3 hours
|
||||
ok = mnesia:dirty_write(#report{
|
||||
id = <<"r_avg">>, reporter_id = <<"u1">>, target_type = calendar,
|
||||
target_id = <<"c1">>, reason = <<"spam">>, status = reviewed,
|
||||
created_at = Created, resolved_at = Resolved, resolved_by = <<"adm">>
|
||||
}),
|
||||
wait_counter({report_resolved_count, reviewed}, 1, 20),
|
||||
Avg = core_report:avg_resolution_time(reviewed),
|
||||
?assertEqual(3.0, Avg).
|
||||
|
||||
wait_counter(Key, Expected, 0) ->
|
||||
Actual = core_stats:with_counter(Key, fun() -> -999 end),
|
||||
?assertEqual(Expected, Actual);
|
||||
wait_counter(Key, Expected, N) ->
|
||||
case core_stats:with_counter(Key, fun() -> -999 end) of
|
||||
Expected -> ok;
|
||||
_ ->
|
||||
timer:sleep(25),
|
||||
wait_counter(Key, Expected, N - 1)
|
||||
end.
|
||||
@@ -0,0 +1,198 @@
|
||||
-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.
|
||||
Reference in New Issue
Block a user