Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/live_sync/replication_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule LiveSync.ReplicationTest do
alias LiveSync.Replication
alias LiveSync.Repo

@moduletag cleanup: ["ignored", "examples"]
@moduletag cleanup: ["example_tags", "ignored", "examples"]

setup do
LiveSync.start_link(repo: Repo, otp_app: :live_sync)
Expand Down
8 changes: 4 additions & 4 deletions lib/live_sync/socket.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ defmodule LiveSync.Socket do
:delete

%{} = value ->
{schema, id} = LiveSync.lookup_info(value)
lookup = LiveSync.lookup_info(value)

Enum.find_value(operations, fn {op, record} ->
if record.__struct__ == schema and record.id == id do
if LiveSync.lookup_info(record) == lookup do
op
end
end)
Expand Down Expand Up @@ -206,9 +206,9 @@ defmodule LiveSync.Socket do
update.__struct__ == assoc.related and
Map.get(update, assoc.related_key) != Map.get(parent, assoc.owner_key)
end)
|> Enum.map(fn {_lookup, {_op, update}} -> update.id end)
|> Enum.map(fn {lookup, {_op, _update}} -> lookup end)

Enum.filter(list, &(is_map(&1) && &1.id not in records_to_remove))
Enum.filter(list, &(is_map(&1) && LiveSync.lookup_info(&1) not in records_to_remove))
end

defp maybe_remove_from_association(record, _parent, _assoc, _updates), do: record
Expand Down
20 changes: 20 additions & 0 deletions lib/live_sync/socket_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule LiveSync.SocketTest do
use LiveSync.ConnCase

alias LiveSync.Example
alias LiveSync.ExampleTag
alias LiveSync.Ignored
alias LiveSync.Repo

Expand Down Expand Up @@ -179,6 +180,25 @@ defmodule LiveSync.SocketTest do
] == Floki.find(parsed_html, ".data-child-name")
end

test "works with associations without an id", %{conn: conn} do
example = Repo.insert!(%Example{organization_id: 1, name: "replication", enabled: false})
Repo.insert!(%ExampleTag{name: "tag", example_id: example.id})

{:ok, view, html} = conn |> get("/#{example.id}") |> live()

parsed_html = Floki.parse_document!(html)
assert parsed_html |> Floki.find(".data-tag-name") |> Floki.text() == "tag"

Repo.update!(change(example, name: "more replication"))

assert_receive :synced
html = render(view)

parsed_html = Floki.parse_document!(html)
assert parsed_html |> Floki.find("#data-name") |> Floki.text() == "more replication"
assert parsed_html |> Floki.find(".data-tag-name") |> Floki.text() == "tag"
end

test "ignores non-watched schemas", %{conn: conn} do
example = Repo.insert!(%Example{organization_id: 1, name: "replication", enabled: false})
ignore = Repo.insert!(%Ignored{organization_id: 1, name: "ignore", example_id: example.id})
Expand Down
9 changes: 9 additions & 0 deletions lib/test_helper.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
LiveSync.Repo.start_link()
LiveSync.Endpoint.start_link()

LiveSync.Repo.query!("DROP TABLE IF EXISTS example_tags;")
LiveSync.Repo.query!("DROP TABLE IF EXISTS ignored;")
LiveSync.Repo.query!("DROP TABLE IF EXISTS examples;")
LiveSync.Repo.query("DROP PUBLICATION live_sync;")
Expand Down Expand Up @@ -28,6 +29,14 @@ CREATE TABLE ignored (
);
""")

LiveSync.Repo.query!("""
CREATE TABLE example_tags (
name text,
example_id bytea REFERENCES examples(id),
PRIMARY KEY (name, example_id)
);
""")

Ecto.Migration.Runner.run(LiveSync.Repo, LiveSync.Repo.config(), 1, LiveSync.Migration, :forward, :up, :up, [])

ExUnit.start(capture_log: true)
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule LiveSync.MixProject do
def project do
[
app: :live_sync,
version: "0.1.11",
version: "0.1.12",
elixir: "~> 1.17",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
1 change: 1 addition & 0 deletions test/support/example.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ defmodule LiveSync.Example do
belongs_to :parent, LiveSync.Example, type: :binary_id, foreign_key: :parent_id
has_many :children, LiveSync.Example, foreign_key: :parent_id
has_many :ignored, LiveSync.Ignored, foreign_key: :example_id
has_many :example_tags, LiveSync.ExampleTag, foreign_key: :example_id
end

def changeset(struct \\ %__MODULE__{}, params) do
Expand Down
13 changes: 13 additions & 0 deletions test/support/example_tag.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule LiveSync.ExampleTag do
@moduledoc false
use Ecto.Schema

# a join style schema with a composite primary key and no `id` field
@primary_key false

schema "example_tags" do
field :name, :string, primary_key: true

belongs_to :example, LiveSync.Example, type: :binary_id, foreign_key: :example_id, primary_key: true
end
end
3 changes: 2 additions & 1 deletion test/support/live_page.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule LiveSync.LivePage do
alias LiveSync.Repo

def mount(%{"id" => id}, session, socket) do
data = LiveSync.Example |> Repo.get!(id) |> Repo.preload([:parent, :children, :ignored])
data = LiveSync.Example |> Repo.get!(id) |> Repo.preload([:parent, :children, :ignored, :example_tags])
{:ok, assign(socket, examples: [data], data: data, test: session["test"])}
end

Expand All @@ -36,6 +36,7 @@ defmodule LiveSync.LivePage do
<p :if={not is_nil(@data.parent)} id="data-parent-name">{@data.parent.name}</p>
<p :for={child <- @data.children} class="data-child-name">{child.name}</p>
<p :for={ignored <- @data.ignored} class="data-ignored-name">{ignored.name}</p>
<p :for={tag <- @data.example_tags} class="data-tag-name">{tag.name}</p>
</div>
<div id="examples">
<div :for={example <- @examples}>
Expand Down
Loading