-module(core_subscription_tests). -include_lib("eunit/include/eunit.hrl"). -include("records.hrl"). setup() -> mnesia:start(), mnesia:create_table(subscription, [ {attributes, record_info(fields, subscription)}, {ram_copies, [node()]} ]), mnesia:create_table(calendar, [ {attributes, record_info(fields, calendar)}, {ram_copies, [node()]} ]), ok. cleanup(_) -> mnesia:delete_table(calendar), mnesia:delete_table(subscription), mnesia:stop(), ok. core_subscription_test_() -> {foreach, fun setup/0, fun cleanup/1, [ {"Create trial subscription", fun test_create_trial/0}, {"Create paid subscription", fun test_create_paid/0}, {"Create monthly duration", fun test_create_monthly_duration/0}, {"Create quarterly duration", fun test_create_quarterly_duration/0}, {"Create biannual duration", fun test_create_biannual_duration/0}, {"Create annual duration", fun test_create_annual_duration/0}, {"Get active by user", fun test_get_active_by_user/0}, {"List by user", fun test_list_by_user/0}, {"Update status", fun test_update_status/0}, {"Check expired", fun test_check_expired/0} ]}. test_create_trial() -> UserId = <<"user123">>, {ok, Sub} = core_subscription:create(UserId, trial, false), ?assertEqual(UserId, Sub#subscription.user_id), ?assertEqual(trial, Sub#subscription.plan), ?assertEqual(false, Sub#subscription.trial_used), ?assertEqual(active, Sub#subscription.status). test_create_paid() -> UserId = <<"user123">>, {ok, Sub} = core_subscription:create(UserId, monthly, true), ?assertEqual(UserId, Sub#subscription.user_id), ?assertEqual(monthly, Sub#subscription.plan), ?assertEqual(true, Sub#subscription.trial_used), ?assertEqual(active, Sub#subscription.status). %% Длительность не зависит от trial_used — только от Plan (месяц ≈ 30 дней). %% add_months считает по календарным дням от полуночи даты старта. assert_plan_duration(Sub, Months) -> {{Y1, M1, D1}, _} = Sub#subscription.started_at, {{Y2, M2, D2}, Time2} = Sub#subscription.expires_at, StartDays = calendar:date_to_gregorian_days({Y1, M1, D1}), EndDays = calendar:date_to_gregorian_days({Y2, M2, D2}), ?assertEqual(Months * 30, EndDays - StartDays), ?assertEqual({0, 0, 0}, Time2). test_create_monthly_duration() -> %% Даже при trial_used=false длительность = 1 месяц, не «trial 30 дней» отдельно {ok, Sub} = core_subscription:create(<<"u-m">>, monthly, false), ?assertEqual(false, Sub#subscription.trial_used), assert_plan_duration(Sub, 1). test_create_quarterly_duration() -> {ok, Sub} = core_subscription:create(<<"u-q">>, quarterly, false), ?assertEqual(false, Sub#subscription.trial_used), assert_plan_duration(Sub, 3). test_create_biannual_duration() -> {ok, Sub} = core_subscription:create(<<"u-b">>, biannual, true), assert_plan_duration(Sub, 6). test_create_annual_duration() -> {ok, Sub} = core_subscription:create(<<"u-a">>, annual, false), assert_plan_duration(Sub, 12). test_get_active_by_user() -> UserId = <<"user123">>, {ok, Sub1} = core_subscription:create(UserId, trial, false), {ok, Sub2} = core_subscription:create(UserId, monthly, true), core_subscription:update_status(Sub1#subscription.id, expired), {ok, Active} = core_subscription:get_active_by_user(UserId), ?assertEqual(Sub2#subscription.id, Active#subscription.id). test_list_by_user() -> UserId = <<"user123">>, {ok, _} = core_subscription:create(UserId, trial, false), {ok, _} = core_subscription:create(UserId, monthly, true), {ok, Subs} = core_subscription:list_by_user(UserId), ?assertEqual(2, length(Subs)). test_update_status() -> UserId = <<"user123">>, {ok, Sub} = core_subscription:create(UserId, trial, false), {ok, Cancelled} = core_subscription:update_status(Sub#subscription.id, cancelled), ?assertEqual(cancelled, Cancelled#subscription.status). test_check_expired() -> UserId = <<"user123">>, % Создаём подписку с истёкшим сроком {ok, Sub} = core_subscription:create(UserId, trial, false), % Принудительно устанавливаем expires_at в прошлое Past = {{2020, 1, 1}, {0, 0, 0}}, mnesia:dirty_write(Sub#subscription{expires_at = Past}), core_subscription:check_expired(), {ok, Updated} = core_subscription:get_by_id(Sub#subscription.id), ?assertEqual(expired, Updated#subscription.status).