zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

domain.test.exs (11991B)


      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.Intent.Domain do
     19 use ZenflowsTest.Help.EctoCase, async: true
     20 
     21 alias Ecto.Changeset
     22 alias Zenflows.VF.{
     23 	Action,
     24 	Agent,
     25 	EconomicResource,
     26 	Intent,
     27 	Intent.Domain,
     28 	Measure,
     29 	Process,
     30 	ResourceSpecification,
     31 	SpatialThing,
     32 }
     33 
     34 setup do
     35 	%{
     36 		params: %{
     37 			action_id: Factory.build(:action_id),
     38 			input_of_id: Factory.insert!(:process).id,
     39 			output_of_id: Factory.insert!(:process).id,
     40 			provider_id: Factory.insert!(:agent).id,
     41 			receiver_id: Factory.insert!(:agent).id,
     42 			resource_inventoried_as_id: Factory.insert!(:economic_resource).id,
     43 			resource_conforms_to_id: Factory.insert!(:resource_specification).id,
     44 			resource_classified_as: Factory.str_list("uri"),
     45 			resource_quantity: %{
     46 				has_unit_id: Factory.insert!(:unit).id,
     47 				has_numerical_value: Factory.decimal(),
     48 			},
     49 			effort_quantity: %{
     50 				has_unit_id: Factory.insert!(:unit).id,
     51 				has_numerical_value: Factory.decimal(),
     52 			},
     53 			available_quantity: %{
     54 				has_unit_id: Factory.insert!(:unit).id,
     55 				has_numerical_value: Factory.decimal(),
     56 			},
     57 			has_beginning: Factory.now(),
     58 			has_end: Factory.now(),
     59 			has_point_in_time: Factory.now(),
     60 			due: Factory.now(),
     61 			finished: Factory.bool(),
     62 			at_location_id: Factory.insert!(:spatial_thing).id,
     63 			name: Factory.str("name"),
     64 			note: Factory.str("note"),
     65 			# in_scope_of_id:
     66 			agreed_in: Factory.str("uri"),
     67 		},
     68 		inserted: Factory.insert!(:intent),
     69 	}
     70 end
     71 
     72 describe "one/1" do
     73 	test "with good id: finds the Intent", %{inserted: %{id: id}} do
     74 		assert {:ok, %Intent{}} = Domain.one(id)
     75 	end
     76 
     77 	test "with bad id: doesn't find the Intent" do
     78 		assert {:error, "not found"} = Domain.one(Factory.id())
     79 	end
     80 end
     81 
     82 describe "create/1" do
     83 	test "with good params (with only :provider): creates an Intent", %{params: params} do
     84 		params = Map.put(params, :receiver_id, nil)
     85 		assert {:ok, %Intent{} = int} = Domain.create(params)
     86 
     87 		keys = ~w[
     88 			action_id
     89 			provider_id receiver_id
     90 			input_of_id output_of_id
     91 			resource_inventoried_as_id resource_conforms_to_id resource_classified_as
     92 			has_beginning has_end has_point_in_time due
     93 			finished name note agreed_in at_location_id
     94 		]a # in_scope_of_id
     95 		assert Map.take(int, keys) == Map.take(params, keys)
     96 
     97 		assert int.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id
     98 		assert Decimal.eq?(int.resource_quantity_has_numerical_value, params.resource_quantity.has_numerical_value)
     99 		assert int.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id
    100 		assert Decimal.eq?(int.effort_quantity_has_numerical_value, params.effort_quantity.has_numerical_value)
    101 		assert int.available_quantity_has_unit_id == params.available_quantity.has_unit_id
    102 		assert Decimal.eq?(int.available_quantity_has_numerical_value, params.available_quantity.has_numerical_value)
    103 	end
    104 
    105 	test "with good params (with only :receiver): creates an Intent", %{params: params} do
    106 		params = Map.put(params, :provider_id, nil)
    107 		assert {:ok, %Intent{} = int} = Domain.create(params)
    108 
    109 		keys = ~w[
    110 			action_id
    111 			provider_id receiver_id
    112 			input_of_id output_of_id
    113 			resource_inventoried_as_id resource_conforms_to_id resource_classified_as
    114 			has_beginning has_end has_point_in_time due
    115 			finished name note agreed_in at_location_id
    116 		]a # in_scope_of_id
    117 		assert Map.take(int, keys) == Map.take(params, keys)
    118 
    119 		assert int.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id
    120 		assert Decimal.eq?(int.resource_quantity_has_numerical_value, params.resource_quantity.has_numerical_value)
    121 		assert int.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id
    122 		assert Decimal.eq?(int.effort_quantity_has_numerical_value, params.effort_quantity.has_numerical_value)
    123 		assert int.available_quantity_has_unit_id == params.available_quantity.has_unit_id
    124 		assert Decimal.eq?(int.available_quantity_has_numerical_value, params.available_quantity.has_numerical_value)
    125 	end
    126 
    127 	test "with bad params (with both :provider and :receiver): doesn't create an Intent", %{params: params} do
    128 		assert {:error, %Changeset{errors: errs}} = Domain.create(params)
    129 		assert {:ok, _} = Keyword.fetch(errs, :provider_id)
    130 		assert {:ok, _} = Keyword.fetch(errs, :receiver_id)
    131 	end
    132 
    133 	test "with bad params: doesn't create an Intent" do
    134 		assert {:error, %Changeset{}} = Domain.create(%{})
    135 	end
    136 end
    137 
    138 describe "update/2" do
    139 	test "with good params (with only :provider): updates the Intent", %{params: params} do
    140 		params = Map.put(params, :receiver_id, nil)
    141 		old = Factory.insert!(:intent, %{receiver: nil, provider: Factory.build(:agent)})
    142 		assert {:ok, %Intent{} = new} = Domain.update(old.id, params)
    143 
    144 		keys = ~w[
    145 			action_id
    146 			provider_id receiver_id
    147 			input_of_id output_of_id
    148 			resource_inventoried_as_id resource_conforms_to_id resource_classified_as
    149 			has_beginning has_end has_point_in_time due
    150 			finished name note agreed_in at_location_id
    151 		]a # in_scope_of_id
    152 		assert Map.take(new, keys) == Map.take(params, keys)
    153 
    154 		assert new.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id
    155 		assert Decimal.eq?(new.resource_quantity_has_numerical_value, params.resource_quantity.has_numerical_value)
    156 		assert new.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id
    157 		assert Decimal.eq?(new.effort_quantity_has_numerical_value, params.effort_quantity.has_numerical_value)
    158 		assert new.available_quantity_has_unit_id == params.available_quantity.has_unit_id
    159 		assert Decimal.eq?(new.available_quantity_has_numerical_value, params.available_quantity.has_numerical_value)
    160 	end
    161 
    162 	test "with good params (with only :receiver): updates the Intent", %{params: params} do
    163 		params = Map.put(params, :provider_id, nil)
    164 		old = Factory.insert!(:intent, %{provider: nil, receiver: Factory.build(:agent)})
    165 		assert {:ok, %Intent{} = new} = Domain.update(old.id, params)
    166 
    167 		keys = ~w[
    168 			action_id
    169 			provider_id receiver_id
    170 			input_of_id output_of_id
    171 			resource_inventoried_as_id resource_conforms_to_id resource_classified_as
    172 			has_beginning has_end has_point_in_time due
    173 			finished name note agreed_in at_location_id
    174 		]a # in_scope_of_id
    175 		assert Map.take(new, keys) == Map.take(params, keys)
    176 
    177 		assert new.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id
    178 		assert Decimal.eq?(new.resource_quantity_has_numerical_value, params.resource_quantity.has_numerical_value)
    179 		assert new.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id
    180 		assert Decimal.eq?(new.effort_quantity_has_numerical_value, params.effort_quantity.has_numerical_value)
    181 		assert new.available_quantity_has_unit_id == params.available_quantity.has_unit_id
    182 		assert Decimal.eq?(new.available_quantity_has_numerical_value, params.available_quantity.has_numerical_value)
    183 	end
    184 
    185 	test "with bad params (with both :provider and :receiver): updates the Intent", %{params: params} do
    186 		int = Factory.insert!(:intent, %{provider: Factory.build(:agent), receiver: nil})
    187 		assert {:error, %Changeset{errors: errs}} = Domain.update(int.id, params)
    188 
    189 		assert {:ok, _} = Keyword.fetch(errs, :provider_id)
    190 		assert {:ok, _} = Keyword.fetch(errs, :receiver_id)
    191 	end
    192 
    193 	test "with bad params (with both :receiver and :provider): updates the Intent", %{params: params} do
    194 		int = Factory.insert!(:intent, %{provider: nil, receiver: Factory.build(:agent)})
    195 		assert {:error, %Changeset{errors: errs}} = Domain.update(int.id, params)
    196 
    197 		assert {:ok, _} = Keyword.fetch(errs, :provider_id)
    198 		assert {:ok, _} = Keyword.fetch(errs, :receiver_id)
    199 	end
    200 
    201 	test "with bad params: doesn't update the Intent", %{inserted: old} do
    202 		assert {:ok, %Intent{} = new} = Domain.update(old.id, %{})
    203 		keys = ~w[
    204 			action_id
    205 			provider_id receiver_id
    206 			input_of_id output_of_id
    207 			resource_inventoried_as_id resource_conforms_to_id resource_classified_as
    208 			resource_quantity_has_unit_id resource_quantity_has_numerical_value
    209 			effort_quantity_has_unit_id effort_quantity_has_numerical_value
    210 			available_quantity_has_unit_id available_quantity_has_numerical_value
    211 			has_beginning has_end has_point_in_time due
    212 			finished name note agreed_in at_location_id
    213 		]a # in_scope_of_id
    214 		assert Map.take(new, keys) == Map.take(old, keys)
    215 	end
    216 end
    217 
    218 describe "delete/1" do
    219 	test "with good id: deletes the Intent", %{inserted: %{id: id}} do
    220 		assert {:ok, %Intent{id: ^id}} = Domain.delete(id)
    221 		assert {:error, "not found"} = Domain.one(id)
    222 	end
    223 
    224 	test "with bad id: doesn't delete the Intent" do
    225 		assert {:error, "not found"} = Domain.delete(Factory.id())
    226 	end
    227 end
    228 
    229 describe "preload/2" do
    230 	test "preloads `:action`", %{inserted: %{id: id}} do
    231 		assert {:ok, int} =  Domain.one(id)
    232 		int = Domain.preload(int, :action)
    233 		assert %Action{} = int.action
    234 	end
    235 
    236 	test "preloads `:input_of`", %{inserted: %{id: id}} do
    237 		assert {:ok, int} =  Domain.one(id)
    238 		int = Domain.preload(int, :input_of)
    239 		assert %Process{} = int.input_of
    240 	end
    241 
    242 	test "preloads `:output_of`", %{inserted: %{id: id}} do
    243 		assert {:ok, int} =  Domain.one(id)
    244 		int = Domain.preload(int, :output_of)
    245 		assert %Process{} = int.output_of
    246 	end
    247 
    248 	test "preloads `:provider`" do
    249 		%{id: id} =
    250 			Factory.insert!(:intent, %{provider: Factory.build(:agent), receiver: nil})
    251 
    252 		assert {:ok, int} =  Domain.one(id)
    253 		int = Domain.preload(int, :provider)
    254 		assert %Agent{} = int.provider
    255 	end
    256 
    257 	test "preloads `:receiver`" do
    258 		%{id: id} =
    259 			Factory.insert!(:intent, %{provider: nil, receiver: Factory.build(:agent)})
    260 
    261 		assert {:ok, int} =  Domain.one(id)
    262 		int = Domain.preload(int, :receiver)
    263 		assert %Agent{} = int.receiver
    264 	end
    265 
    266 	test "preloads `:resource_inventoried_as`", %{inserted: %{id: id}} do
    267 		assert {:ok, int} =  Domain.one(id)
    268 		int = Domain.preload(int, :resource_inventoried_as)
    269 		assert %EconomicResource{} = int.resource_inventoried_as
    270 	end
    271 
    272 	test "preloads `:resource_conforms_to`", %{inserted: %{id: id}} do
    273 		assert {:ok, int} =  Domain.one(id)
    274 		int = Domain.preload(int, :resource_conforms_to)
    275 		assert %ResourceSpecification{} = int.resource_conforms_to
    276 	end
    277 
    278 	test "preloads `:resource_quantity`", %{inserted: %{id: id}} do
    279 		assert {:ok, int} =  Domain.one(id)
    280 		int = Domain.preload(int, :resource_quantity)
    281 		assert %Measure{} = int.resource_quantity
    282 	end
    283 
    284 	test "preloads `:effort_quantity`", %{inserted: %{id: id}} do
    285 		assert {:ok, int} =  Domain.one(id)
    286 		int = Domain.preload(int, :effort_quantity)
    287 		assert %Measure{} = int.effort_quantity
    288 	end
    289 
    290 	test "preloads `:available_quantity`", %{inserted: %{id: id}} do
    291 		assert {:ok, int} =  Domain.one(id)
    292 		int = Domain.preload(int, :available_quantity)
    293 		assert %Measure{} = int.available_quantity
    294 	end
    295 
    296 	test "preloads `:at_location`", %{inserted: %{id: id}} do
    297 		assert {:ok, int} =  Domain.one(id)
    298 		int = Domain.preload(int, :at_location)
    299 		assert %SpatialThing{} = int.at_location
    300 	end
    301 
    302 	test "preloads `:published_in`", %{inserted: %{id: id}} do
    303 		assert {:ok, int} =  Domain.one(id)
    304 
    305 		assert [] = Domain.preload(int, :published_in).published_in
    306 
    307 		left =
    308 			Enum.map(0..9, fn _ ->
    309 				Factory.insert!(:proposed_intent, %{publishes: int}).id
    310 			end)
    311 		right =
    312 			Domain.preload(int, :published_in)
    313 			|> Map.fetch!(:published_in)
    314 			|> Enum.map(& &1.id)
    315 		assert left -- right == []
    316 	end
    317 end
    318 end