Issue with nested resource with test / context

Hey I am loosely following some example blogpost to implement some context with 2 schemas in it.

Accounts context contains user and credential schema

# credential schema
  schema "credentials" do
    field :email, :string
    field :password, :string, virtual: true
    field :password_hash, :string
    belongs_to :user, User

    timestamps(type: :utc_datetime_usec)
  end

  @doc false
  def changeset(credential, attrs) do
    credential
    |> cast(attrs, [:email, :password])
    |> validate_required([:email, :password])
    |> unique_constraint(:email)
    |> put_password_hash()
  end
# user schema
  schema "users" do
    field :name, :string
    field :username, :string
    has_one :credential, Credential

    timestamps(type: :utc_datetime_usec)
  end

  @doc false
  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :username])
    |> validate_required([:name, :username])
    |> unique_constraint(:username)
  end
# Accounts context method
def create_user(attrs \\ %{}) do
    %User{}
    |> User.changeset(attrs)
    |> Ecto.Changeset.cast_assoc(:credential, with: &Credential.changeset/2)
    |> Repo.insert()
  end
# Accounts context test
@valid_attrs %{
  name: "some name",
  username: "some username",
  credential: %{
    email: 'some email',
    password: "some password"
  }
}

test "create_user/1 with valid data creates a user" do
  assert {:ok, %User{} = user} = Accounts.create_user(@valid_attrs)
  assert user.name == "some name"
  assert user.username == "some username"
end

This test case fails because left != right because the creation leads to an error on the changeset side.
Testing it manually in iex shows the same result.

#Ecto.Changeset<
   action: :insert,
   changes: %{
     credential: #Ecto.Changeset<
       action: :insert,
       changes: %{password: "some password"},
       errors: [email: {"is invalid", [type: :string, validation: :cast]}],
       data: #Barysphere.Accounts.Credential<>,
       valid?: false
     >,
     name: "some name",
     username: "some username"
   },
   errors: [],
   data: #Barysphere.Accounts.User<>,
   valid?: false
 >}

I got stuck for some time now with this issue and need some guidance. Maybe someone can hint me in the right direction or knows the solution.

best regards
denym_

NVM fixed it. Rubberduck for the win.
Typecasting was the issue. '' is different to "".

1 Like