1

How to automatically serialize ecto struct to json response in channel test? As I can see in documentation The event’s message must be a serializable map, I found in answer and in tutorial that when I use Poison.Encoder in model then any message passed via Transport (as I understand) layer should be encoded.

Example model:

use PhoenixTrello.Web, :model
  # ...

  @derive {Poison.Encoder, only: [:id, :first_name, :last_name, :email]}

  # ...
end

broadcast from one of channel functions:

broadcast_from! socket, "card:created", %{card: card}

finally attempt to receive payload from broadcast in test:

assert_receive %Phoenix.Socket.Broadcast{topic: ^t1, event: "card:created", payload: ^payload}

then it rises not match error with not serialized struct in payload (I'm trying to match only derived model filelds):

Process mailbox:
  %Phoenix.Socket.Broadcast{event: "card:created", payload: %{card: %PhoenixTrello.Card{__meta__: #Ecto.Schema.Metadata<:loaded, "cards">, ... user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 1833}}, topic: "boards:1833"}

How to get serialized json message in test as if it was the client app?

opHASnoNAME
  • 20,224
  • 26
  • 98
  • 143
luzny
  • 2,380
  • 7
  • 30
  • 64
  • Why do you expect a client to receive `Phoenix.Socket.Broadcast`?! When we do bullhorn “Hello world,” our mates are to hear single “Hello world” message, rather than to get punched by the bullhorn itself :) – Aleksei Matiushkin Feb 24 '17 at 05:10

1 Answers1

0

I'd first assert_receive the raw message and then Poison.encode! and do a second assert:

payload = "{\"card\": ...}"
assert_receive %Phoenix.Socket.Broadcast{topic: ^t1, event: "card:created", payload: raw_payload}
assert Poison.encode!(raw_payload) == payload
Dogbert
  • 212,659
  • 41
  • 396
  • 397
  • But why I can't get already encoded payload? I'm wondering where is it encoded by Phoenix and where can I intercept complete response? – luzny Mar 03 '17 at 09:48
  • I think [this](https://github.com/phoenixframework/phoenix/blob/074a584ae324f78fa89f7ca097c38f8805d3021e/lib/phoenix/transports/websocket.ex#L190-L192) line handles the JSON encoding. This happens very late as far as I can tell, after the Elixir messages have been sent to the test process. – Dogbert Mar 03 '17 at 20:31