-
Notifications
You must be signed in to change notification settings - Fork 343
Expand file tree
/
Copy pathconstraints_test.exs
More file actions
102 lines (84 loc) · 3.37 KB
/
Copy pathconstraints_test.exs
File metadata and controls
102 lines (84 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
defmodule Ecto.Integration.ConstraintsTest do
use ExUnit.Case, async: true
import Ecto.Migrator, only: [up: 4]
alias Ecto.Integration.PoolRepo
defmodule ConstraintMigration do
use Ecto.Migration
@table table(:constraints_test)
def change do
create @table do
add :price, :integer
add :from, :integer
add :to, :integer
end
# Only valid after MySQL 8.0.19
create constraint(@table.name, :positive_price, check: "price > 0")
end
end
defmodule Constraint do
use Ecto.Integration.Schema
schema "constraints_test" do
field :price, :integer
field :from, :integer
field :to, :integer
end
end
@base_migration 2_000_000
setup_all do
ExUnit.CaptureLog.capture_log(fn ->
num = @base_migration + System.unique_integer([:positive])
up(PoolRepo, num, ConstraintMigration, log: false)
end)
:ok
end
@tag :create_constraint
test "check constraint" do
# When the changeset doesn't expect the db error
changeset = Ecto.Changeset.change(%Constraint{}, price: -10)
exception =
assert_raise Ecto.ConstraintError, ~r/constraint error when attempting to insert struct/, fn ->
PoolRepo.insert(changeset)
end
assert exception.message =~ "\"positive_price\" (check_constraint)"
assert exception.message =~ "The changeset has not defined any constraint."
assert exception.message =~ "call `check_constraint/3`"
# When the changeset does expect the db error, but doesn't give a custom message
{:error, changeset} =
changeset
|> Ecto.Changeset.check_constraint(:price, name: :positive_price)
|> PoolRepo.insert()
assert changeset.errors == [price: {"is invalid", [constraint: :check, constraint_name: "positive_price"]}]
assert changeset.data.__meta__.state == :built
# When the changeset does expect the db error and gives a custom message
changeset = Ecto.Changeset.change(%Constraint{}, price: -10)
{:error, changeset} =
changeset
|> Ecto.Changeset.check_constraint(:price, name: :positive_price, message: "price must be greater than 0")
|> PoolRepo.insert()
assert changeset.errors == [price: {"price must be greater than 0", [constraint: :check, constraint_name: "positive_price"]}]
assert changeset.data.__meta__.state == :built
# When the change does not violate the check constraint
changeset = Ecto.Changeset.change(%Constraint{}, price: 10, from: 100, to: 200)
{:ok, changeset} =
changeset
|> Ecto.Changeset.check_constraint(:price, name: :positive_price, message: "price must be greater than 0")
|> PoolRepo.insert()
assert is_integer(changeset.id)
end
@tag :create_constraint
test "custom :constraint_handler option" do
parent = self()
custom_handler = fn _err, _opts ->
send(parent, :custom_handler_called)
[exclusion: "positive_price"]
end
changeset =
%Constraint{}
|> Ecto.Changeset.change(price: -10)
|> Ecto.Changeset.exclusion_constraint(:price, name: :positive_price)
{:error, changeset} = PoolRepo.insert(changeset, constraint_handler: custom_handler)
assert_received :custom_handler_called
assert changeset.errors == [price: {"violates an exclusion constraint", [constraint: :exclusion, constraint_name: "positive_price"]}]
assert changeset.data.__meta__.state == :built
end
end