duration.test.exs (6076B)
1 # Zenflows is designed to implement the Valueflows vocabulary, 2 # written and maintained by srfsh <info@dyne.org>. 3 # Copyright (C) 2021-2023 Dyne.org foundation <foundation@dyne.org>. 4 # 5 # This program is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU Affero General Public License as published by 7 # the Free Software Foundation, either version 3 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU Affero General Public License for more details. 14 # 15 # You should have received a copy of the GNU Affero General Public License 16 # along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 defmodule ZenflowsTest.VF.Duration do 19 use ZenflowsTest.Help.EctoCase, async: true 20 21 alias Ecto.Changeset 22 23 defmodule Dummy do 24 use Ecto.Schema 25 26 alias Ecto.Changeset 27 alias Zenflows.VF.{Duration, TimeUnit} 28 29 embedded_schema do 30 field :has_duration, :map, virtual: true 31 field :has_duration_unit_type, TimeUnit 32 field :has_duration_numeric_duration, :decimal 33 end 34 35 def changeset(params) do 36 %__MODULE__{} 37 |> common(params) 38 |> Map.put(:action, :insert) 39 end 40 41 def changeset(schema, params) do 42 schema 43 |> common(params) 44 |> Map.put(:action, :update) 45 end 46 47 defp common(schema, params) do 48 schema 49 |> Changeset.cast(params, [:has_duration]) 50 |> Duration.cast(:has_duration) 51 end 52 end 53 54 setup do 55 %{ 56 params: %{ 57 unit_type: Factory.build(:time_unit), 58 numeric_duration: Factory.decimal(), 59 }, 60 inserted: %Dummy{ 61 has_duration_unit_type: Factory.build(:time_unit), 62 has_duration_numeric_duration: Factory.decimal(), 63 }, 64 } 65 end 66 67 test "insert", %{params: params} do 68 # no changes when params is `%{}` 69 assert %Changeset{valid?: true, changes: %{}} = Dummy.changeset(%{}) 70 71 # fields are nil when `:has_duration` is `nil` 72 assert %Changeset{valid?: true, changes: chgs} = Dummy.changeset(%{has_duration: nil}) 73 assert chgs.has_duration_unit_type == nil 74 assert chgs.has_duration_numeric_duration == nil 75 76 # fields are properly set when `:has_duration` is properly set 77 assert %Changeset{valid?: true, changes: chgs} = Dummy.changeset(%{has_duration: params}) 78 assert chgs.has_duration_unit_type == params.unit_type 79 assert Decimal.eq?(chgs.has_duration_numeric_duration, params.numeric_duration) 80 81 # when no fields are provided, no fields are set 82 assert %Changeset{valid?: false, changes: chgs, errors: errs} 83 = Dummy.changeset(%{has_duration: %{}}) 84 assert length(Keyword.get_values(errs, :has_duration)) == 2 85 refute Map.has_key?(chgs, :has_duration_unit_type) 86 or Map.has_key?(chgs, :has_duration_numeric_duration) 87 88 # when `:unit_type` is `nil`, no fields are set 89 assert %Changeset{valid?: false, changes: chgs, errors: errs} 90 = Dummy.changeset(%{has_duration: %{unit_type: nil}}) 91 assert length(Keyword.get_values(errs, :has_duration)) == 2 92 refute Map.has_key?(chgs, :has_duration_unit_type) 93 or Map.has_key?(chgs, :has_duration_numeric_duration) 94 95 # when `:numeric_duration` is `nil`, no fields are set 96 assert %Changeset{valid?: false, changes: %{has_duration: _}, errors: errs} 97 = Dummy.changeset(%{has_duration: %{numeric_duration: nil}}) 98 assert length(Keyword.get_values(errs, :has_duration)) == 2 99 refute Map.has_key?(chgs, :has_duration_unit_type) 100 or Map.has_key?(chgs, :has_duration_numeric_duration) 101 102 # when both fields are `nil`, no fields are set 103 assert %Changeset{valid?: false, changes: %{has_duration: _}, errors: errs} 104 = Dummy.changeset(%{has_duration: %{unit_type: nil, numeric_duration: nil}}) 105 assert length(Keyword.get_values(errs, :has_duration)) == 2 106 refute Map.has_key?(chgs, :has_duration_unit_type) 107 or Map.has_key?(chgs, :has_duration_numeric_duration) 108 end 109 110 test "update", %{params: params, inserted: schema} do 111 # no changes when params is `%{}` 112 assert %Changeset{valid?: true, changes: %{}} = Dummy.changeset(schema, %{}) 113 114 # fields are nil when `:has_duration` is `nil` 115 assert %Changeset{valid?: true, changes: %{ 116 has_duration_unit_type: nil, 117 has_duration_numeric_duration: nil, 118 }} = Dummy.changeset(schema, %{has_duration: nil}) 119 120 # fields are changed when `:has_duration` is properly set 121 assert %Changeset{valid?: true, changes: chgs} 122 = Dummy.changeset(schema, %{has_duration: params}) 123 # since ecto won't change it if it is already there 124 if schema.has_duration_unit_type != params.unit_type, 125 do: assert chgs.has_duration_unit_type == params.unit_type 126 assert Decimal.eq?(chgs.has_duration_numeric_duration, params.numeric_duration) 127 128 # when no fields are provided, no fields are set 129 assert %Changeset{valid?: false, changes: chgs, errors: errs} 130 = Dummy.changeset(schema, %{has_duration: %{}}) 131 assert length(Keyword.get_values(errs, :has_duration)) == 2 132 refute Map.has_key?(chgs, :has_duration_unit_type) 133 or Map.has_key?(chgs, :has_duration_numeric_duration) 134 135 # when `:unit_type` is `nil`, no fields are set 136 assert %Changeset{valid?: false, changes: chgs, errors: errs} 137 = Dummy.changeset(schema, %{has_duration: %{unit_type: nil}}) 138 assert length(Keyword.get_values(errs, :has_duration)) == 2 139 refute Map.has_key?(chgs, :has_duration_unit_type) 140 or Map.has_key?(chgs, :has_duration_numeric_duration) 141 142 # when `:numeric_duration` is `nil`, no fields are set 143 assert %Changeset{valid?: false, changes: %{has_duration: _}, errors: errs} 144 = Dummy.changeset(schema, %{has_duration: %{numeric_duration: nil}}) 145 assert length(Keyword.get_values(errs, :has_duration)) == 2 146 refute Map.has_key?(chgs, :has_duration_unit_type) 147 or Map.has_key?(chgs, :has_duration_numeric_duration) 148 149 # when both fields are `nil`, no fields are set 150 assert %Changeset{valid?: false, changes: %{has_duration: _}, errors: errs} 151 = Dummy.changeset(schema, %{has_duration: %{unit_type: nil, numeric_duration: nil}}) 152 assert length(Keyword.get_values(errs, :has_duration)) == 2 153 refute Map.has_key?(chgs, :has_duration_unit_type) 154 or Map.has_key?(chgs, :has_duration_numeric_duration) 155 end 156 end