-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
defmodule Trento.Auditing do | ||
@moduledoc """ | ||
Auditing module | ||
""" | ||
|
||
require Logger | ||
|
||
require Trento.Auditing.RetentionPeriodUnit, as: RetentionPeriodUnit | ||
|
||
alias Trento.Auditing.Settings | ||
|
||
alias Trento.Repo | ||
|
||
@spec get_settings() :: | ||
{:ok, Settings.t()} | {:error, :auditing_settings_not_configured} | ||
def get_settings do | ||
case Repo.one(Settings.base_query()) do | ||
%Settings{} = settings -> {:ok, settings} | ||
nil -> {:error, :auditing_settings_not_configured} | ||
end | ||
end | ||
|
||
@spec save_retention_period(integer(), RetentionPeriodUnit.t()) :: | ||
{:ok, Settings.t()} | {:error, :auditing_settings_already_configured} | ||
def save_retention_period(retention_period, unit \\ RetentionPeriodUnit.days()) do | ||
with {:ok, :auditing_settings_not_configured} <- ensure_no_settings_configured() do | ||
nil | ||
|> save_or_update_settings(retention_period, unit) | ||
|> log_error("Error while saving auditing retention period") | ||
end | ||
end | ||
|
||
@spec change_retention_period(integer(), RetentionPeriodUnit.t()) :: {:ok, Settings.t()} | ||
def change_retention_period(retention_period, unit \\ RetentionPeriodUnit.days()) do | ||
with {:ok, settings} <- get_settings() do | ||
settings | ||
|> save_or_update_settings(retention_period, unit) | ||
|> log_error("Error while updating auditing retention period") | ||
end | ||
end | ||
|
||
defp ensure_no_settings_configured do | ||
case Repo.one(Settings.base_query()) do | ||
nil -> | ||
{:ok, :auditing_settings_not_configured} | ||
|
||
%Settings{} -> | ||
Logger.error("Error: Auditing settings already configured.") | ||
{:error, :auditing_settings_already_configured} | ||
end | ||
end | ||
|
||
defp save_or_update_settings(current_retention_period, retention_period, unit) do | ||
case current_retention_period do | ||
nil -> | ||
%Settings{} | ||
|> Settings.changeset(%{ | ||
retention_period: retention_period, | ||
retention_period_unit: unit | ||
}) | ||
|> Repo.insert() | ||
|
||
%Settings{} -> | ||
current_retention_period | ||
|> Settings.changeset(%{ | ||
retention_period: retention_period, | ||
retention_period_unit: unit | ||
}) | ||
|> Repo.update() | ||
end | ||
end | ||
|
||
defp log_error({:error, _} = error, message) do | ||
Logger.error("#{message}: #{inspect(error)}") | ||
error | ||
end | ||
|
||
defp log_error(result, _), do: result | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,255 @@ | ||
defmodule Trento.AuditingTest do | ||
use ExUnit.Case | ||
use Trento.DataCase | ||
|
||
import Mox | ||
|
||
import Trento.Factory | ||
|
||
alias Trento.Auditing | ||
alias Trento.Auditing.Settings | ||
|
||
require Trento.Auditing.RetentionPeriodUnit, as: RetentionPeriodUnit | ||
|
||
setup :verify_on_exit! | ||
|
||
describe "retrieving auditing settings" do | ||
test "should return an error when settings are not available" do | ||
assert {:error, :auditing_settings_not_configured} == Auditing.get_settings() | ||
end | ||
|
||
test "should return settings" do | ||
%{ | ||
retention_period: retention_period, | ||
retention_period_unit: retention_period_unit | ||
} = insert(:auditing_settings) | ||
|
||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^retention_period, | ||
retention_period_unit: ^retention_period_unit | ||
}} = Auditing.get_settings() | ||
end | ||
end | ||
|
||
@validation_scenarios [ | ||
%{ | ||
invalid_retention_periods: [-1, 0], | ||
expected_errors: [ | ||
retention_period: | ||
{"must be greater than %{number}", | ||
[validation: :number, kind: :greater_than, number: 0]} | ||
] | ||
}, | ||
%{ | ||
invalid_retention_periods: [nil, "", " "], | ||
expected_errors: [retention_period: {"can't be blank", [validation: :required]}] | ||
} | ||
] | ||
|
||
describe "saving auditing settings" do | ||
test "should not accept settings if previously saved" do | ||
insert(:auditing_settings) | ||
|
||
assert {:error, :auditing_settings_already_configured} = | ||
Auditing.save_retention_period(42, RetentionPeriodUnit.weeks()) | ||
end | ||
|
||
test "should not accept invalid retention periods" do | ||
for %{ | ||
invalid_retention_periods: invalid_retention_periods, | ||
expected_errors: expected_errors | ||
} <- @validation_scenarios do | ||
Enum.each(invalid_retention_periods, fn invalid_retention_period -> | ||
retention_period_unit = Faker.Util.pick(RetentionPeriodUnit.values()) | ||
|
||
assert {:error, | ||
%{ | ||
errors: ^expected_errors | ||
}} = | ||
Auditing.save_retention_period(invalid_retention_period, retention_period_unit) | ||
end) | ||
end | ||
end | ||
|
||
test "should not accept unsupported retention period units" do | ||
for retention_period_unit <- [:foo, :bar, :baz] do | ||
assert {:error, | ||
%{ | ||
errors: [ | ||
retention_period_unit: {"is invalid", _} | ||
] | ||
}} = Auditing.save_retention_period(42, retention_period_unit) | ||
end | ||
end | ||
|
||
scenarios = [ | ||
%{ | ||
name: "default retention period unit", | ||
retention_period: 42, | ||
expected_retention_period_unit: RetentionPeriodUnit.days() | ||
}, | ||
%{ | ||
name: "days", | ||
retention_period: 1, | ||
retention_period_unit: RetentionPeriodUnit.days() | ||
}, | ||
%{ | ||
name: "weeks", | ||
retention_period: 3, | ||
retention_period_unit: RetentionPeriodUnit.weeks() | ||
}, | ||
%{ | ||
name: "months", | ||
retention_period: 5, | ||
retention_period_unit: RetentionPeriodUnit.months() | ||
}, | ||
%{ | ||
name: "years", | ||
retention_period: 7, | ||
retention_period_unit: RetentionPeriodUnit.years() | ||
} | ||
] | ||
|
||
for %{name: name} = scenario <- scenarios do | ||
@scenario scenario | ||
|
||
test "should save valid retention periods #{name}" do | ||
%{retention_period: retention_period} = @scenario | ||
|
||
expected_retention_period_unit = | ||
Map.get(@scenario, :retention_period_unit, RetentionPeriodUnit.days()) | ||
|
||
case Map.has_key?(@scenario, :retention_period_unit) do | ||
true -> | ||
retention_period_unit = Map.fetch!(@scenario, :retention_period_unit) | ||
|
||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^retention_period, | ||
retention_period_unit: ^expected_retention_period_unit | ||
}} = | ||
Auditing.save_retention_period(retention_period, retention_period_unit) | ||
|
||
false -> | ||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^retention_period, | ||
retention_period_unit: RetentionPeriodUnit.days() | ||
}} = | ||
Auditing.save_retention_period(retention_period) | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "changing auditing settings" do | ||
test "should not be able to change retention time if no auditing settings were previously saved" do | ||
assert {:error, :auditing_settings_not_configured} == | ||
Auditing.change_retention_period(42, RetentionPeriodUnit.days()) | ||
end | ||
|
||
test "should not accept invalid retention periods" do | ||
insert(:auditing_settings) | ||
|
||
for %{ | ||
invalid_retention_periods: invalid_retention_periods, | ||
expected_errors: expected_errors | ||
} <- @validation_scenarios do | ||
Enum.each(invalid_retention_periods, fn invalid_retention_period -> | ||
retention_period_unit = Faker.Util.pick(RetentionPeriodUnit.values()) | ||
|
||
assert {:error, | ||
%{ | ||
errors: ^expected_errors | ||
}} = | ||
Auditing.change_retention_period( | ||
invalid_retention_period, | ||
retention_period_unit | ||
) | ||
end) | ||
end | ||
end | ||
|
||
test "should not accept unsupported retention period units" do | ||
insert(:auditing_settings) | ||
|
||
for retention_period_unit <- [:foo, :bar, :baz] do | ||
assert {:error, | ||
%{ | ||
errors: [ | ||
retention_period_unit: {"is invalid", _} | ||
] | ||
}} = Auditing.change_retention_period(42, retention_period_unit) | ||
end | ||
end | ||
|
||
scenarios = [ | ||
%{ | ||
name: "default retention period unit", | ||
retention_period: 42, | ||
expected_retention_period_unit: RetentionPeriodUnit.days() | ||
}, | ||
%{ | ||
name: "days", | ||
retention_period: 1, | ||
retention_period_unit: RetentionPeriodUnit.days() | ||
}, | ||
%{ | ||
name: "weeks", | ||
retention_period: 3, | ||
retention_period_unit: RetentionPeriodUnit.weeks() | ||
}, | ||
%{ | ||
name: "months", | ||
retention_period: 5, | ||
retention_period_unit: RetentionPeriodUnit.months() | ||
}, | ||
%{ | ||
name: "years", | ||
retention_period: 7, | ||
retention_period_unit: RetentionPeriodUnit.years() | ||
} | ||
] | ||
|
||
for %{name: name} = scenario <- scenarios do | ||
@scenario scenario | ||
|
||
test "should save valid retention periods #{name}" do | ||
%{ | ||
retention_period: initial_retention_period, | ||
Check warning on line 220 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 220 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 220 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 220 in test/trento/auditing_test.exs GitHub Actions / Test
|
||
retention_period_unit: initial_retention_period_unit | ||
Check warning on line 221 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 221 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 221 in test/trento/auditing_test.exs GitHub Actions / Test
Check warning on line 221 in test/trento/auditing_test.exs GitHub Actions / Test
|
||
} = | ||
insert(:auditing_settings, | ||
retention_period: 92, | ||
retention_period_unit: RetentionPeriodUnit.years() | ||
) | ||
|
||
%{retention_period: retention_period} = @scenario | ||
|
||
expected_retention_period_unit = | ||
Map.get(@scenario, :retention_period_unit, RetentionPeriodUnit.days()) | ||
|
||
case Map.has_key?(@scenario, :retention_period_unit) do | ||
true -> | ||
retention_period_unit = Map.fetch!(@scenario, :retention_period_unit) | ||
|
||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^retention_period, | ||
retention_period_unit: ^expected_retention_period_unit | ||
}} = | ||
Auditing.change_retention_period(retention_period, retention_period_unit) | ||
|
||
false -> | ||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^retention_period, | ||
retention_period_unit: RetentionPeriodUnit.days() | ||
}} = | ||
Auditing.change_retention_period(retention_period) | ||
end | ||
end | ||
end | ||
end | ||
end |