beam-community / ex_machina

Create test data for Elixir applications
https://hex.pm/packages/ex_machina
MIT License
1.93k stars 146 forks source link

Test Failure Due to insert_belongs_to_assocs/2 Overwriting Parameter #445

Closed adonig closed 3 months ago

adonig commented 6 months ago

Description

I encountered an issue in my test setup where a parameter is unexpectedly set by insert_belongs_to_assocs/2, causing a test case to fail.

Current Behavior

Here's the test snippet:

      attrs = params_with_assocs(:hyperlink, source_id: "invalid")
      IO.inspect(attrs)
      changeset = Hyperlink.changeset(%Hyperlink{}, attrs)
      refute changeset.valid?

The IO.inspect/1 outputs the following, showing that source_id is set to a valid hash, rather than the intended "invalid":

%{
  source_id: "775adc233d133ff96f25a64934fecc07e33055f1679bda74cd7c412c9c989b15",
  target_id: "622a55ea583fb59a5f9547171d821ad2a30f63d1911d598b21f270fa84d126f2",
  anchor_text: "A test anchor text"
}

Proposed Solution

To address this, I propose passing the attrs to insert_belongs_to_assocs/2 to check if the owner_key is already present in attrs before calling insert_build_belongs_to_assoc/3. This change would skip association insertion when the owner_key is explicitly provided, allowing for more controlled test setups and preventing unintended data setup.

Here’s a suggested modification to lib/ex_machina/ecto.ex:

  @doc false
  def params_with_assocs(module, factory_name, attrs \\ %{}) do
    factory_name
    |> module.build(attrs)
    |> insert_belongs_to_assocs(module, attrs)
    |> recursively_strip
  end

  defp insert_belongs_to_assocs(%{__struct__: struct} = record, module, attrs) do
    assocations = struct.__schema__(:associations)

    Enum.reduce(assocations, record, fn association_name, record ->
      case struct.__schema__(:association, association_name) do
        association = %{__struct__: Ecto.Association.BelongsTo, owner_key: key} ->
          if Map.has_key?(attrs, key) do
            record
          else
            insert_built_belongs_to_assoc(module, association, record)
          end

        _ ->
          record
      end
    end)
  end

I am happy to submit a PR if this solution aligns with the project's goals.

Let me know if you need further modifications or additional details for the issue!

adonig commented 5 months ago

Did ExMachina get abandoned? That would be kind of sad 😞

github-actions[bot] commented 4 months ago

This issue has been automatically marked as "stale:discard". We are sorry that we haven't been able to prioritize it yet. If this issue still relevant, please leave any comment if you have any new additional information that helps to solve this issue. We encourage you to create a pull request, if you can. We are happy to help you with that.

github-actions[bot] commented 3 months ago

Closing this issue after a prolonged period of inactivity. If this issue is still relevant, feel free to re-open the issue. Thank you!