stavro / arc_ecto

An integration with Arc and Ecto.
255 stars 149 forks source link

Ex_machina integration #33

Closed asiniy closed 8 years ago

asiniy commented 8 years ago

ex_machina is a de-facto standard for pre-building models in ExUnit. Unfortunately, I can't force it to work with arc_ecto. I'm not sure why:

defmodule MyReelty.Factory do
  use ExMachina.Ecto, repo: MyReelty.Repo

  def factory(:review) do
    %MyReelty.Review{
      city:            "Las Vegas",
      state:           "Nevada",
      country:         "USA",
      address:         "11th avenue",
      thumbnail_type:  "screenshot",
      zipcode:         1234,
      video:           %{file_name: "sample.mp4"}
    }
  end
end

And exception:

  1) test invalid parameters (MyReelty.Api.ReviewControllerTest)
     test/controllers/api/review_controller_test.exs:36
     ** (FunctionClauseError) no function clause matching in Arc.Ecto.Type.dump/2
     stacktrace:
       (arc_ecto) lib/arc_ecto/type.ex:19: Arc.Ecto.Type.dump(MyReelty.Video, %Plug.Upload{content_type: nil, filename: "sample.mp4", path: "test/fixtures/sample.mp4"})
       (ecto) lib/ecto/query/planner.ex:29: anonymous fn/6 in Ecto.Query.Planner.fields/4
       (stdlib) lists.erl:1262: :lists.foldl/3
       (ecto) lib/ecto/query/planner.ex:21: Ecto.Query.Planner.fields/4
       (ecto) lib/ecto/repo/schema.ex:449: Ecto.Repo.Schema.dump_changes/5
       (ecto) lib/ecto/repo/schema.ex:77: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
       (ecto) lib/ecto/repo/schema.ex:477: anonymous fn/3 in Ecto.Repo.Schema.wrap_in_transaction/9
       (ecto) lib/ecto/pool.ex:292: Ecto.Pool.with_rollback/3
       (ecto) lib/ecto/adapters/sql.ex:582: Ecto.Adapters.SQL.transaction/8
       (ecto) lib/ecto/pool.ex:244: Ecto.Pool.outer_transaction/6
       (ecto) lib/ecto/adapters/sql.ex:551: Ecto.Adapters.SQL.transaction/3
       (ecto) lib/ecto/repo/schema.ex:14: Ecto.Repo.Schema.insert!/4
       (ex_machina) lib/ex_machina/ecto.ex:157: ExMachina.Ecto.save_record/3
       test/controllers/api/review_controller_test.exs:45: MyReelty.Api.ReviewControllerTest.__ex_unit_setup_1/1
       test/controllers/api/review_controller_test.exs:1: MyReelty.Api.ReviewControllerTest.__ex_unit__/

Is there any plans for further ex_machina integration? Thanks!

gullitmiranda commented 8 years ago

@asiniy try use %{file_name: "sample.mp4", updated_at: nil}

asiniy commented 8 years ago

I'm getting this kind of error:

  1) test GET index lists reviews marked as unappropriate (MyReelty.Admin.UnappropriateControllerTest)
     test/controllers/admin/unappropriate_controller_test.exs:26
     ** (FunctionClauseError) no function clause matching in Ecto.DateTime.to_erl/1
     stacktrace:
       (ecto) lib/ecto/date_time.ex:615: Ecto.DateTime.to_erl(nil)
       (arc_ecto) lib/arc_ecto/type.ex:20: Arc.Ecto.Type.dump/2
       (ecto) lib/ecto/query/planner.ex:29: anonymous fn/6 in Ecto.Query.Planner.fields/4
       (stdlib) lists.erl:1262: :lists.foldl/3
       (ecto) lib/ecto/query/planner.ex:21: Ecto.Query.Planner.fields/4
       (ecto) lib/ecto/repo/schema.ex:449: Ecto.Repo.Schema.dump_changes/5
       (ecto) lib/ecto/repo/schema.ex:77: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
       (ecto) lib/ecto/repo/schema.ex:477: anonymous fn/3 in Ecto.Repo.Schema.wrap_in_transaction/9
       (ecto) lib/ecto/pool.ex:292: Ecto.Pool.with_rollback/3
       (ecto) lib/ecto/adapters/sql.ex:582: Ecto.Adapters.SQL.transaction/8
       (ecto) lib/ecto/pool.ex:244: Ecto.Pool.outer_transaction/6
       (ecto) lib/ecto/adapters/sql.ex:551: Ecto.Adapters.SQL.transaction/3
       (ecto) lib/ecto/repo/schema.ex:14: Ecto.Repo.Schema.insert!/4
       (ex_machina) lib/ex_machina/ecto.ex:157: ExMachina.Ecto.save_record/3
       test/controllers/admin/unappropriate_controller_test.exs:11: MyReelty.Admin.UnappropriateControllerTest.__ex_unit_setup_1/1
       test/controllers/admin/unappropriate_controller_test.exs:1: MyReelty.Admin.UnappropriateControllerTest.__ex_unit__/2
gullitmiranda commented 8 years ago

@asiniy which version of arc_ecto are you using?

asiniy commented 8 years ago

@gullitmiranda updated to 0.4.2. Now I have

  1) test GET index lists reviews marked as unappropriate (MyReelty.Admin.UnappropriateControllerTest)
     test/controllers/admin/unappropriate_controller_test.exs:26
     ** (FunctionClauseError) no function clause matching in Arc.Ecto.Type.dump/2
     stacktrace:
       (arc_ecto) lib/arc_ecto/type.ex:19: Arc.Ecto.Type.dump(MyReelty.Video, %{file_name: "test/fixtures/sample.mp4"})
       (ecto) lib/ecto/query/planner.ex:29: anonymous fn/6 in Ecto.Query.Planner.fields/4
       (stdlib) lists.erl:1262: :lists.foldl/3
       (ecto) lib/ecto/query/planner.ex:21: Ecto.Query.Planner.fields/4
       (ecto) lib/ecto/repo/schema.ex:449: Ecto.Repo.Schema.dump_changes/5
       (ecto) lib/ecto/repo/schema.ex:77: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
       (ecto) lib/ecto/repo/schema.ex:477: anonymous fn/3 in Ecto.Repo.Schema.wrap_in_transaction/9
       (ecto) lib/ecto/pool.ex:292: Ecto.Pool.with_rollback/3
       (ecto) lib/ecto/adapters/sql.ex:582: Ecto.Adapters.SQL.transaction/8
       (ecto) lib/ecto/pool.ex:244: Ecto.Pool.outer_transaction/6
       (ecto) lib/ecto/adapters/sql.ex:551: Ecto.Adapters.SQL.transaction/3
       (ecto) lib/ecto/repo/schema.ex:14: Ecto.Repo.Schema.insert!/4
       (ex_machina) lib/ex_machina/ecto.ex:157: ExMachina.Ecto.save_record/3
       test/controllers/admin/unappropriate_controller_test.exs:11: MyReelty.Admin.UnappropriateControllerTest.__ex_unit_setup_1/1
       test/controllers/admin/unappropriate_controller_test.exs:1: MyReelty.Admin.UnappropriateControllerTest.__ex_unit__/2

My factory:

  def factory(:review) do
    %MyReelty.Review{
      city:            "Las Vegas",
      state:           "Nevada",
      country:         "USA",
      address:         "11th avenue",
      thumbnail_type:  "screenshot",
      zipcode:         1234,
      video:           %{ file_name: "test/fixtures/sample.mp4", updated_at: nil },
    }
  end
gullitmiranda commented 8 years ago

it seems that the ex_machina is removing the field updated_at. By chance the :ex_machina is this outdated?

asiniy commented 8 years ago

It's modern.

video:           %{ file_name: "test/fixtures/sample.mp4", updated_at: Ecto.DateTime.now },

solved the problem

ArturT commented 7 years ago

Ecto.DateTime.now is not available anymore. You can use Ecto.DateTime.utc.

cubeguerrero commented 7 years ago

Hi,

I tried using

video: %{ file_name: "test/fixtures/sample.mp4", updated_at: Ecto.DateTime.now },

and I'm getting the following error: screen shot 2017-03-12 at 10 31 55 am

My mix.exs screen shot 2017-03-12 at 10 33 31 am

Anyone also encountering the same error?

stavro commented 7 years ago

@fatbotdesigns replace file_name with filename

cubeguerrero commented 7 years ago

Hi @stavro,

I did that and got the following error: screen shot 2017-03-12 at 3 13 03 pm

Looking at your code: I also tried passing:

All them doesn't work. :(

ArturT commented 7 years ago

Have you tried?

video: %{ file_name: "test/fixtures/sample.mp4", updated_at: Ecto.DateTime.utc },

What is in your article_test.exs ?

cubeguerrero commented 7 years ago

@ArturT tried that already. that was the first I thing I tried

my article_test has the following: screen shot 2017-03-12 at 3 50 22 pm

My factory.exs has the following screen shot 2017-03-12 at 3 51 11 pm

ArturT commented 7 years ago

@fatbotdesigns The problem is because you have insert(:article) and the result of it is passed to Article.changeset.

The Arc expects the %Plug.Upload{} https://github.com/stavro/arc/blob/master/lib/arc/file.ex#L39

Here is how I'm doing it: Note there is filename instead of file_name and there is path instead of updated_at.

valid_attrs = {file: %Plug.Upload{path: "test/fixtures/attachment.pdf", filename: "attachment.pdf"}
changeset = Article.changeset(%Article{}, valid_attrs)
assert changeset.valid?
nsweeting commented 6 years ago

I tried many versions of this. Basically just wanted to create an asset record without storing anything. As per the cast function: https://github.com/stavro/arc_ecto/blob/a30a3dbb436524390f80dc0b1d165b7e3443b4ad/lib/arc_ecto/type.ex#L7 - only thing that ended up working for me within the actual factory file was:

defmodule MyApp.AssetFactory do
  defmacro __using__(_opts) do
    quote do
      def asset_factory do
        %MyApp.Asset{
          attachment: %{
            "file_name" => "test.png",
            "updated_at" => Ecto.DateTime.utc()
          }
        } 
      end
    end
  end
end
richeterre commented 6 years ago

@nsweeting Nice! However, I noticed that under certain circumstances ex_machina still converts the string keys to atoms internally before casting, so cast/2 receives this:

%{file_name: "test.png", updated_at: #Ecto.DateTime<2018-03-23 14:40:49>}

which fails to match the pattern and makes the test crash. Could this be solved by making arc_ecto also match on atom keys, like so:

def cast(_definition, %{file_name: file, updated_at: updated_at}) do

In fact, the inverse seems to happen for Arc.Ecto.Type.dump/2, which is called with string keys by ex_machina when trying to pass an existing struct as an association to a factory. It all works if both cast/2 and dump/2 match both string and atom keys, but would this be too hacky to add?

(cc @stavro)