Skip to content

Commit b515cd6

Browse files
authored
Merge pull request #1339 from code-corps/1317-update-conversation-for-conversation-part
Update conversation for new conversation part
2 parents fb8e05d + 731fb8f commit b515cd6

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

lib/code_corps/messages/conversation_parts.ex

+30-5
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,48 @@ defmodule CodeCorps.Messages.ConversationParts do
44
i.e. a reply to the `CodeCorps.Conversation` by any participant.
55
"""
66

7-
import Ecto.Changeset, only: [assoc_constraint: 2, cast: 3, validate_required: 2,
8-
validate_inclusion: 3]
7+
import Ecto.Changeset, only: [
8+
assoc_constraint: 2,
9+
cast: 3,
10+
validate_required: 2,
11+
validate_inclusion: 3
12+
]
913

1014
alias CodeCorps.{
15+
Conversation,
1116
ConversationPart,
17+
Messages,
1218
Repo
1319
}
1420
alias CodeCorpsWeb.ConversationChannel
21+
alias Ecto.{
22+
Changeset,
23+
Multi
24+
}
1525

16-
@spec create(map) :: ConversationPart.t | Ecto.Changeset.t
17-
def create(attrs) do
18-
with {:ok, %ConversationPart{} = conversation_part} <- %ConversationPart{} |> create_changeset(attrs) |> Repo.insert() do
26+
@spec create(map) :: {:ok, ConversationPart.t} | {:error, Changeset.t}
27+
def create(%{"conversation_id" => id} = attrs) do
28+
with %Conversation{} = conversation <- Repo.get(Conversation, id),
29+
{:ok, %ConversationPart{} = conversation_part} <- do_create(attrs, conversation) do
1930
ConversationChannel.broadcast_new_conversation_part(conversation_part)
2031
{:ok, conversation_part}
2132
end
2233
end
2334

35+
@spec do_create(map, Conversation.t) :: {:ok, Conversation.t} | {:error, Changeset.t}
36+
defp do_create(attrs, conversation) do
37+
Multi.new
38+
|> Multi.insert(:conversation_part, create_changeset(%ConversationPart{}, attrs))
39+
|> Multi.update(:conversation, Messages.Conversations.part_added_changeset(conversation))
40+
|> Repo.transaction()
41+
|> marshall_result()
42+
end
43+
44+
@spec marshall_result(tuple) :: {:ok, ConversationPart.t} | {:error, Changeset.t}
45+
defp marshall_result({:ok, %{conversation_part: %ConversationPart{} = conversation_part}}), do: {:ok, conversation_part}
46+
defp marshall_result({:error, :conversation_part, %Changeset{} = changeset, _steps}), do: {:error, changeset}
47+
defp marshall_result({:error, :conversation, %Changeset{} = changeset, _steps}), do: {:error, changeset}
48+
2449
@doc false
2550
@spec create_changeset(ConversationPart.t, map) :: Ecto.Changeset.t
2651
def create_changeset(%ConversationPart{} = conversation_part, attrs) do

lib/code_corps/messages/conversations.ex

+12
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,16 @@ defmodule CodeCorps.Messages.Conversations do
1616
|> Changeset.validate_required([:user_id])
1717
|> Changeset.assoc_constraint(:user)
1818
end
19+
20+
@doc false
21+
@spec part_added_changeset(Conversation.t) :: Ecto.Changeset.t
22+
def part_added_changeset(%Conversation{} = conversation) do
23+
params = %{
24+
status: "open",
25+
updated_at: Ecto.DateTime.utc()
26+
}
27+
28+
conversation
29+
|> Changeset.cast(params, [:status, :updated_at])
30+
end
1931
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule CodeCorps.Messages.ConversationsTest do
2+
@moduledoc false
3+
4+
use CodeCorps.DbAccessCase
5+
6+
alias CodeCorps.{
7+
Conversation, Messages
8+
}
9+
10+
describe "part_added_changeset/1" do
11+
test "sets the updated_at to the current time" do
12+
old_updated_at = Timex.now |> Timex.shift(days: -5)
13+
conversation = %Conversation{updated_at: old_updated_at}
14+
changeset = conversation |> Messages.Conversations.part_added_changeset()
15+
assert changeset.changes[:updated_at] > old_updated_at
16+
end
17+
18+
test "sets status to open" do
19+
conversation = %Conversation{status: "closed"}
20+
changeset = conversation |> Messages.Conversations.part_added_changeset()
21+
assert changeset.changes[:status] == "open"
22+
end
23+
end
24+
end

test/lib/code_corps/messages/messages_test.exs

+12-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ defmodule CodeCorps.MessagesTest do
1414
records |> Enum.map(&Map.get(&1, :id)) |> Enum.sort
1515
end
1616

17+
defp json_map(attrs) do
18+
attrs
19+
|> Poison.encode!
20+
|> Poison.decode!
21+
end
22+
1723
describe "list" do
1824
test "returns all records by default" do
1925
insert_list(3, :message)
@@ -249,15 +255,15 @@ defmodule CodeCorps.MessagesTest do
249255

250256
describe "add_part/1" do
251257
test "creates a conversation part" do
252-
conversation = insert(:conversation)
258+
conversation = insert(:conversation, updated_at: Timex.now |> Timex.shift(minutes: -5))
253259
user = insert(:user)
254260
attrs = %{
255261
author_id: user.id,
256262
body: "Test body",
257263
conversation_id: conversation.id
258264
}
259265

260-
{:ok, %ConversationPart{} = conversation_part} = Messages.add_part(attrs)
266+
{:ok, %ConversationPart{} = conversation_part} = Messages.add_part(attrs |> json_map())
261267

262268
conversation_part =
263269
conversation_part
@@ -266,6 +272,7 @@ defmodule CodeCorps.MessagesTest do
266272
assert conversation_part.author_id == user.id
267273
assert conversation_part.body == "Test body"
268274
assert conversation_part.conversation_id == conversation.id
275+
assert conversation_part.updated_at == conversation_part.conversation.updated_at
269276
end
270277

271278
test "broadcasts event on phoenix channel" do
@@ -278,7 +285,7 @@ defmodule CodeCorps.MessagesTest do
278285
}
279286

280287
CodeCorpsWeb.Endpoint.subscribe("conversation:#{conversation.id}")
281-
{:ok, %ConversationPart{id: id}} = Messages.add_part(attrs)
288+
{:ok, %ConversationPart{id: id}} = Messages.add_part(attrs |> json_map())
282289
assert_broadcast("new:conversation-part", %{id: ^id})
283290
CodeCorpsWeb.Endpoint.unsubscribe("conversation:#{conversation.id}")
284291
end
@@ -295,7 +302,7 @@ defmodule CodeCorps.MessagesTest do
295302
conversation_id: conversation.id
296303
}
297304

298-
{:ok, %ConversationPart{} = part} = Messages.add_part(attrs)
305+
{:ok, %ConversationPart{} = part} = Messages.add_part(attrs |> json_map())
299306

300307
part = part |> Repo.preload([:author, conversation: [message: [[project: :organization]]]])
301308

@@ -317,7 +324,7 @@ defmodule CodeCorps.MessagesTest do
317324
conversation_id: conversation.id
318325
}
319326

320-
{:ok, %ConversationPart{} = part} = Messages.add_part(attrs)
327+
{:ok, %ConversationPart{} = part} = Messages.add_part(attrs |> json_map())
321328

322329
part = part |> Repo.preload([:author, conversation: [message: [[project: :organization]]]])
323330

0 commit comments

Comments
 (0)