defmodule BDS.ImportDefinitionsTest do use ExUnit.Case, async: false alias BDS.ImportDefinitions setup do :ok = Ecto.Adapters.SQL.Sandbox.checkout(BDS.Repo) temp_dir = Path.join(System.tmp_dir!(), "bds-import-definitions-#{System.unique_integer([:positive])}") File.mkdir_p!(temp_dir) on_exit(fn -> File.rm_rf(temp_dir) end) {:ok, project} = BDS.Projects.create_project(%{name: "Import Definitions", data_path: temp_dir}) %{project: project, temp_dir: temp_dir} end test "decode_analysis_result does not create atoms from unknown keys" do unique_suffix = :erlang.unique_integer() unknown_key_1 = "csm001_fictive_#{unique_suffix}" unknown_key_2 = "csm001_nested_#{unique_suffix}" malicious_json = Jason.encode!(%{ unknown_key_1 => "val", "site_info" => %{unknown_key_2 => "nested_val"} }) result = ImportDefinitions.decode_analysis_result(malicious_json) assert is_map(result) assert Map.get(result, unknown_key_1) == "val" or Map.get(result, "csm001_fictive_#{unique_suffix}") == "val" assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key_1) end assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key_2) end end test "decode_analysis_result converts known keys to atoms" do json = Jason.encode!(%{"site_info" => %{"title" => "My Blog"}}) result = ImportDefinitions.decode_analysis_result(json) assert is_map(result) assert Map.get(result, :site_info) != nil or Map.get(result, "site_info") != nil end test "get, update, and delete round-trip import definition editor state", %{ project: project, temp_dir: temp_dir } do uploads_folder_path = Path.join(temp_dir, "uploads") wxr_file_path = Path.join(temp_dir, "legacy.xml") assert {:ok, definition} = ImportDefinitions.create_definition(%{ project_id: project.id, name: "Legacy Import", wxr_file_path: wxr_file_path, uploads_folder_path: uploads_folder_path, last_analysis_result: Jason.encode!(%{site_info: %{title: "Legacy Blog"}}) }) fetched = ImportDefinitions.get_definition(definition.id) assert fetched.id == definition.id assert fetched.project_id == project.id assert fetched.name == "Legacy Import" assert fetched.wxr_file_path == wxr_file_path assert fetched.uploads_folder_path == uploads_folder_path assert fetched.last_analysis_result == Jason.encode!(%{site_info: %{title: "Legacy Blog"}}) assert {:ok, updated} = ImportDefinitions.update_definition(definition.id, %{ name: "Renamed Import", wxr_file_path: Path.join(temp_dir, "renamed.xml"), uploads_folder_path: Path.join(temp_dir, "renamed-uploads"), last_analysis_result: %{ site_info: %{title: "Renamed Blog"}, post_stats: %{new_count: 2} } }) assert updated.name == "Renamed Import" assert updated.wxr_file_path == Path.join(temp_dir, "renamed.xml") assert updated.uploads_folder_path == Path.join(temp_dir, "renamed-uploads") assert updated.last_analysis_result == Jason.encode!(%{site_info: %{title: "Renamed Blog"}, post_stats: %{new_count: 2}}) assert [%{id: listed_id, title: "Renamed Import"}] = ImportDefinitions.list_definitions(project.id) assert listed_id == definition.id assert {:ok, :deleted} = ImportDefinitions.delete_definition(definition.id) assert ImportDefinitions.get_definition(definition.id) == nil end end