-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial auditing settings operations
- Loading branch information
1 parent
62c2b72
commit e9a101a
Showing
3 changed files
with
361 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
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 successfully change retention periods #{name}" do | ||
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 | ||
|
||
test "should successfully handle unchanging retention periods" do | ||
initial_retention_period = 42 | ||
initial_retention_period_unit = RetentionPeriodUnit.days() | ||
|
||
insert(:auditing_settings, | ||
retention_period: initial_retention_period, | ||
retention_period_unit: initial_retention_period_unit | ||
) | ||
|
||
assert {:ok, | ||
%Settings{ | ||
retention_period: ^initial_retention_period, | ||
retention_period_unit: ^initial_retention_period_unit | ||
}} = | ||
Auditing.change_retention_period( | ||
initial_retention_period, | ||
initial_retention_period_unit | ||
) | ||
end | ||
end | ||
end |