timgremore
commited on
Commit
•
8548275
1
Parent(s):
94b2573
feat: Pass chunk to chunk component
Browse files- lib/medical_transcription/classification_server.ex +1 -2
- lib/medical_transcription/transcription_server.ex +8 -7
- lib/medical_transcription/transcriptions.ex +26 -0
- lib/medical_transcription_web/components/transcription_text_component.ex +26 -55
- lib/medical_transcription_web/live/transcriptions_live/show.ex +14 -9
- test/medical_transcription/coding_test.exs +21 -16
- test/medical_transcription_web/live/transcriptions_live_show_test.exs +1 -1
- test/support/fixtures/code_vectors_fixtures.ex +1 -1
lib/medical_transcription/classification_server.ex
CHANGED
@@ -35,7 +35,7 @@ defmodule MedicalTranscription.ClassificationServer do
|
|
35 |
end
|
36 |
|
37 |
@impl GenServer
|
38 |
-
def handle_info({:chunk_updated,
|
39 |
{:chunk, chunk} = state
|
40 |
|
41 |
%TranscriptionChunk{id: id} = chunk
|
@@ -73,7 +73,6 @@ defmodule MedicalTranscription.ClassificationServer do
|
|
73 |
|> Coding.process_chunk()
|
74 |
|> Enum.each(fn %CodeVectorMatch{
|
75 |
code: code,
|
76 |
-
description: description,
|
77 |
cosine_similarity: cosine_similarity,
|
78 |
weighting: [weighting]
|
79 |
} ->
|
|
|
35 |
end
|
36 |
|
37 |
@impl GenServer
|
38 |
+
def handle_info({:chunk_updated, _result}, state) do
|
39 |
{:chunk, chunk} = state
|
40 |
|
41 |
%TranscriptionChunk{id: id} = chunk
|
|
|
73 |
|> Coding.process_chunk()
|
74 |
|> Enum.each(fn %CodeVectorMatch{
|
75 |
code: code,
|
|
|
76 |
cosine_similarity: cosine_similarity,
|
77 |
weighting: [weighting]
|
78 |
} ->
|
lib/medical_transcription/transcription_server.ex
CHANGED
@@ -41,17 +41,18 @@ defmodule MedicalTranscription.TranscriptionServer do
|
|
41 |
|
42 |
%Transcription{id: id} = transcription
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
50 |
|
51 |
Phoenix.PubSub.broadcast(
|
52 |
:medicode_pubsub,
|
53 |
"transcriptions:#{id}",
|
54 |
-
{:transcription_updated,
|
55 |
)
|
56 |
|
57 |
{:noreply, state}
|
|
|
41 |
|
42 |
%Transcription{id: id} = transcription
|
43 |
|
44 |
+
{:ok, chunk} =
|
45 |
+
Transcriptions.create_chunk(%{
|
46 |
+
transcription_id: id,
|
47 |
+
text: result.text,
|
48 |
+
start_mark: result.start_mark,
|
49 |
+
end_mark: result.end_mark
|
50 |
+
})
|
51 |
|
52 |
Phoenix.PubSub.broadcast(
|
53 |
:medicode_pubsub,
|
54 |
"transcriptions:#{id}",
|
55 |
+
{:transcription_updated, chunk}
|
56 |
)
|
57 |
|
58 |
{:noreply, state}
|
lib/medical_transcription/transcriptions.ex
CHANGED
@@ -92,6 +92,32 @@ defmodule MedicalTranscription.Transcriptions do
|
|
92 |
Repo.get!(query, id)
|
93 |
end
|
94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
@doc """
|
96 |
Creates a transcription.
|
97 |
|
|
|
92 |
Repo.get!(query, id)
|
93 |
end
|
94 |
|
95 |
+
@doc """
|
96 |
+
Gets a single transcription chunk.
|
97 |
+
|
98 |
+
Raises `Ecto.NoResultsError` if the TranscriptionChunk does not exist.
|
99 |
+
|
100 |
+
## Examples
|
101 |
+
|
102 |
+
iex> get_transcription_chunk!(123)
|
103 |
+
%TranscriptionChunk{}
|
104 |
+
|
105 |
+
iex> get_transcription_chunk!(456)
|
106 |
+
** (Ecto.NoResultsError)
|
107 |
+
|
108 |
+
"""
|
109 |
+
def get_transcription_chunk!(id, preload_transcription_chunk_associations \\ false) do
|
110 |
+
query =
|
111 |
+
if preload_transcription_chunk_associations do
|
112 |
+
TranscriptionChunk
|
113 |
+
|> preload([:keywords, :code_vectors])
|
114 |
+
else
|
115 |
+
TranscriptionChunk
|
116 |
+
end
|
117 |
+
|
118 |
+
Repo.get!(query, id)
|
119 |
+
end
|
120 |
+
|
121 |
@doc """
|
122 |
Creates a transcription.
|
123 |
|
lib/medical_transcription_web/components/transcription_text_component.ex
CHANGED
@@ -18,20 +18,16 @@ defmodule MedicalTranscriptionWeb.Components.TranscriptionTextComponent do
|
|
18 |
def update(assigns, socket) do
|
19 |
self_pid = self()
|
20 |
|
21 |
-
text = assigns.text
|
22 |
|
23 |
initial_assigns = %{
|
24 |
id: assigns.id,
|
25 |
-
|
26 |
-
end_mark: assigns.end_mark,
|
27 |
-
text: assigns.text
|
28 |
}
|
29 |
|
30 |
socket =
|
31 |
socket
|
32 |
|> assign(initial_assigns)
|
33 |
-
|> assign_async(:tags, fn -> classify_text(text) end)
|
34 |
-
|> assign_async(:keywords, fn -> find_keywords(self_pid, text) end)
|
35 |
|
36 |
{:ok, socket}
|
37 |
end
|
@@ -43,60 +39,39 @@ defmodule MedicalTranscriptionWeb.Components.TranscriptionTextComponent do
|
|
43 |
<div id={@id} class="flex gap-12 pb-10 border-b border-[#444444]/20">
|
44 |
<div class="flex-1 flex flex-col gap-4">
|
45 |
<p
|
46 |
-
:if={!is_nil(@start_mark) && !is_nil(@end_mark)}
|
47 |
class="px-2 text-[32px] leading-normal font-semibold"
|
48 |
>
|
49 |
-
<%= @start_mark %> - <%= @end_mark %>
|
50 |
</p>
|
51 |
|
52 |
<div class="flex-1 w-full text-[28px] leading-normal text-type-black-tertiary">
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
>
|
65 |
-
<.highlight text={@text} keywords={keywords} />
|
66 |
-
</p>
|
67 |
-
</.async_result>
|
68 |
-
</div>
|
69 |
-
|
70 |
-
<div class="flex items-center gap-2 text-sm italic">
|
71 |
-
<.async_result assign={@keywords}>
|
72 |
-
<:loading>
|
73 |
-
<img src={~p"/images/loading.svg"} width="16" class="animate-spin" />
|
74 |
-
Finding keywords...
|
75 |
-
</:loading>
|
76 |
-
<:failed :let={reason}>There was an error finding keywords: <%= reason %></:failed>
|
77 |
-
</.async_result>
|
78 |
</div>
|
79 |
</div>
|
80 |
|
81 |
<div class="flex-1 flex flex-col items-stretch gap-3">
|
82 |
-
<.
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
text={@text}
|
94 |
-
weighting={weighting}
|
95 |
-
/>
|
96 |
-
<% end %>
|
97 |
-
|
98 |
-
<.live_component module={CodeSelect} id={"#{@id}-code-select"} text={@text} />
|
99 |
-
</.async_result>
|
100 |
</div>
|
101 |
</div>
|
102 |
"""
|
@@ -157,8 +132,4 @@ defmodule MedicalTranscriptionWeb.Components.TranscriptionTextComponent do
|
|
157 |
# 2. A fast process finding the phrase closest in vector space to the whole text.
|
158 |
KeywordFinder.find_most_similar_label(text, phrases, 2)
|
159 |
end
|
160 |
-
|
161 |
-
defp code_selected?(code, finalized_codes) do
|
162 |
-
Enum.any?(finalized_codes, code)
|
163 |
-
end
|
164 |
end
|
|
|
18 |
def update(assigns, socket) do
|
19 |
self_pid = self()
|
20 |
|
21 |
+
text = assigns.chunk.text
|
22 |
|
23 |
initial_assigns = %{
|
24 |
id: assigns.id,
|
25 |
+
chunk: assigns.chunk
|
|
|
|
|
26 |
}
|
27 |
|
28 |
socket =
|
29 |
socket
|
30 |
|> assign(initial_assigns)
|
|
|
|
|
31 |
|
32 |
{:ok, socket}
|
33 |
end
|
|
|
39 |
<div id={@id} class="flex gap-12 pb-10 border-b border-[#444444]/20">
|
40 |
<div class="flex-1 flex flex-col gap-4">
|
41 |
<p
|
42 |
+
:if={!is_nil(@chunk.start_mark) && !is_nil(@chunk.end_mark)}
|
43 |
class="px-2 text-[32px] leading-normal font-semibold"
|
44 |
>
|
45 |
+
<%= @chunk.start_mark %> - <%= @chunk.end_mark %>
|
46 |
</p>
|
47 |
|
48 |
<div class="flex-1 w-full text-[28px] leading-normal text-type-black-tertiary">
|
49 |
+
<p class="h-full min-h-full rounded p-2"><%= @chunk.text %></p>
|
50 |
+
<p
|
51 |
+
id={"#{@id}-transcription-text"}
|
52 |
+
contenteditable
|
53 |
+
role="textbox"
|
54 |
+
class="h-full min-h-full rounded p-2"
|
55 |
+
phx-hook="TranscriptionEditor"
|
56 |
+
phx-target={@myself}
|
57 |
+
>
|
58 |
+
<.highlight text={@chunk.text} keywords={@chunk.keywords} />
|
59 |
+
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
</div>
|
61 |
</div>
|
62 |
|
63 |
<div class="flex-1 flex flex-col items-stretch gap-3">
|
64 |
+
<.tag_result
|
65 |
+
:for={code_vector <- @chunk.code_vectors}
|
66 |
+
code_vector_id={code_vector.id}
|
67 |
+
code={code_vector.code}
|
68 |
+
label={code_vector.label}
|
69 |
+
score={1.0}
|
70 |
+
text={@chunk.text}
|
71 |
+
weighting={[1.0]}
|
72 |
+
/>
|
73 |
+
|
74 |
+
<.live_component module={CodeSelect} id={"#{@id}-code-select"} text={@chunk.text} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
</div>
|
76 |
</div>
|
77 |
"""
|
|
|
132 |
# 2. A fast process finding the phrase closest in vector space to the whole text.
|
133 |
KeywordFinder.find_most_similar_label(text, phrases, 2)
|
134 |
end
|
|
|
|
|
|
|
|
|
135 |
end
|
lib/medical_transcription_web/live/transcriptions_live/show.ex
CHANGED
@@ -4,7 +4,6 @@ defmodule MedicalTranscriptionWeb.TranscriptionsLive.Show do
|
|
4 |
alias MedicalTranscription.Audio.RecordingPipeline
|
5 |
alias MedicalTranscription.Repo
|
6 |
alias MedicalTranscription.Transcriptions
|
7 |
-
alias MedicalTranscription.Transcriptions.TranscriptionChunk
|
8 |
|
9 |
alias MedicalTranscriptionWeb.Components.TranscriptionTextComponent
|
10 |
|
@@ -50,16 +49,18 @@ defmodule MedicalTranscriptionWeb.TranscriptionsLive.Show do
|
|
50 |
|
51 |
<main class="flex-1 pl-16 pr-16 pt-[25px]">
|
52 |
<div class="flex flex-col h-full mx-auto max-w-5xl">
|
53 |
-
<.result_heading
|
|
|
|
|
|
|
|
|
54 |
|
55 |
<div id="result_list" class="flex flex flex-col gap-14" phx-update="stream">
|
56 |
<.live_component
|
57 |
:for={{dom_id, chunk} <- @streams.chunks}
|
58 |
module={TranscriptionTextComponent}
|
59 |
id={dom_id}
|
60 |
-
|
61 |
-
end_mark={chunk.end_mark}
|
62 |
-
text={chunk.text}
|
63 |
finalized_codes={@finalized_codes}
|
64 |
/>
|
65 |
</div>
|
@@ -111,7 +112,9 @@ defmodule MedicalTranscriptionWeb.TranscriptionsLive.Show do
|
|
111 |
end
|
112 |
|
113 |
@impl true
|
114 |
-
def handle_info({:transcription_updated,
|
|
|
|
|
115 |
# The processing sends a message as each chunk of text is coded. See here for some background and potential
|
116 |
# inspiration for this: https://elixirforum.com/t/liveview-asynchronous-task-patterns/44695
|
117 |
{:noreply, stream_insert(socket, :chunks, chunk)}
|
@@ -178,9 +181,11 @@ defmodule MedicalTranscriptionWeb.TranscriptionsLive.Show do
|
|
178 |
end
|
179 |
|
180 |
defp get_transcription(id) do
|
181 |
-
id
|
182 |
-
|
183 |
-
|
|
|
|
|
184 |
end
|
185 |
|
186 |
defp list_transcriptions(user), do: Transcriptions.list_transcriptions(user)
|
|
|
4 |
alias MedicalTranscription.Audio.RecordingPipeline
|
5 |
alias MedicalTranscription.Repo
|
6 |
alias MedicalTranscription.Transcriptions
|
|
|
7 |
|
8 |
alias MedicalTranscriptionWeb.Components.TranscriptionTextComponent
|
9 |
|
|
|
49 |
|
50 |
<main class="flex-1 pl-16 pr-16 pt-[25px]">
|
51 |
<div class="flex flex-col h-full mx-auto max-w-5xl">
|
52 |
+
<.result_heading
|
53 |
+
status={@transcription.status}
|
54 |
+
transcription={@transcription}
|
55 |
+
summary_keywords={@summary_keywords}
|
56 |
+
/>
|
57 |
|
58 |
<div id="result_list" class="flex flex flex-col gap-14" phx-update="stream">
|
59 |
<.live_component
|
60 |
:for={{dom_id, chunk} <- @streams.chunks}
|
61 |
module={TranscriptionTextComponent}
|
62 |
id={dom_id}
|
63 |
+
chunk={chunk}
|
|
|
|
|
64 |
finalized_codes={@finalized_codes}
|
65 |
/>
|
66 |
</div>
|
|
|
112 |
end
|
113 |
|
114 |
@impl true
|
115 |
+
def handle_info({:transcription_updated, %{id: chunk_id}}, socket) do
|
116 |
+
chunk = get_transcription_chunk(chunk_id)
|
117 |
+
|
118 |
# The processing sends a message as each chunk of text is coded. See here for some background and potential
|
119 |
# inspiration for this: https://elixirforum.com/t/liveview-asynchronous-task-patterns/44695
|
120 |
{:noreply, stream_insert(socket, :chunks, chunk)}
|
|
|
181 |
end
|
182 |
|
183 |
defp get_transcription(id) do
|
184 |
+
Transcriptions.get_transcription(id, true)
|
185 |
+
end
|
186 |
+
|
187 |
+
defp get_transcription_chunk(id) do
|
188 |
+
Transcriptions.get_transcription_chunk!(id, true)
|
189 |
end
|
190 |
|
191 |
defp list_transcriptions(user), do: Transcriptions.list_transcriptions(user)
|
test/medical_transcription/coding_test.exs
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
defmodule MedicalTranscription.CodingTest do
|
2 |
use MedicalTranscription.DataCase
|
3 |
|
|
|
|
|
4 |
alias MedicalTranscription.Coding
|
5 |
alias MedicalTranscription.Coding.CodeVector
|
6 |
alias MedicalTranscription.Feedback.CodeFeedback
|
@@ -34,6 +36,9 @@ defmodule MedicalTranscription.CodingTest do
|
|
34 |
end
|
35 |
|
36 |
describe "process_chunk/2" do
|
|
|
|
|
|
|
37 |
setup do
|
38 |
create_code_vector!("74685", "Coronary artery anomaly")
|
39 |
create_code_vector!("41412", "Dissection of coronary artery")
|
@@ -41,28 +46,28 @@ defmodule MedicalTranscription.CodingTest do
|
|
41 |
create_code_vector!("V812", "Screening for other and unspecified cardiovascular conditions")
|
42 |
create_code_vector!("V4589", "Other postprocedural status")
|
43 |
|
44 |
-
:
|
45 |
-
|
46 |
|
47 |
-
|
48 |
-
|
49 |
|
50 |
-
test "Codes can be weighted multiple times when multiple prior feedback items exist for a single code" do
|
51 |
# One negative feedback item moves the code from 1st to 4th (x0.9).
|
52 |
# The net result of 2 negative and 1 positive (x0.891) is to remove the code from the results.
|
53 |
create_code_feedback!(@feedback_text, false, "74685")
|
54 |
create_code_feedback!(@feedback_text, true, "74685")
|
55 |
create_code_feedback!(@feedback_text, false, "74685")
|
56 |
-
results = Coding.process_chunk(
|
57 |
|
58 |
assert Enum.map(results, & &1.code) == ["41412", "V717", "V812"]
|
59 |
assert Enum.all?(results, &(&1.weighting == [:none]))
|
60 |
end
|
61 |
|
62 |
-
test "Weighting can cause codes to appear in results that wouldn't have been included from the initial similarity query" do
|
63 |
# E.g. weighting up a code that isn't in the initial results
|
64 |
create_code_feedback!(@feedback_text, true, "V4589")
|
65 |
-
results = Coding.process_chunk(
|
66 |
|
67 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812", "V4589"]
|
68 |
|
@@ -75,32 +80,32 @@ defmodule MedicalTranscription.CodingTest do
|
|
75 |
]
|
76 |
end
|
77 |
|
78 |
-
test "Codes are unweighted when no prior feedback" do
|
79 |
-
results = Coding.process_chunk(
|
80 |
|
81 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812"]
|
82 |
assert Enum.all?(results, &(&1.weighting == [:none]))
|
83 |
end
|
84 |
|
85 |
-
test "Code is ranked higher when prior positive feedback" do
|
86 |
create_code_feedback!(@feedback_text, true, "V717")
|
87 |
-
results = Coding.process_chunk(
|
88 |
|
89 |
assert Enum.map(results, & &1.code) == ["V717", "74685", "41412", "V812"]
|
90 |
assert Enum.map(results, & &1.weighting) == [[:positive], [:none], [:none], [:none]]
|
91 |
end
|
92 |
|
93 |
-
test "Code is ranked lower when prior negative feedback" do
|
94 |
create_code_feedback!(@feedback_text, false, "74685")
|
95 |
-
results = Coding.process_chunk(
|
96 |
|
97 |
assert Enum.map(results, & &1.code) == ["41412", "V717", "V812", "74685"]
|
98 |
assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none], [:negative]]
|
99 |
end
|
100 |
|
101 |
-
test "Code with low similarity score is removed from result when prior negative feedback" do
|
102 |
create_code_feedback!(@feedback_text, false, "V717")
|
103 |
-
results = Coding.process_chunk(
|
104 |
|
105 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V812"]
|
106 |
assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none]]
|
|
|
1 |
defmodule MedicalTranscription.CodingTest do
|
2 |
use MedicalTranscription.DataCase
|
3 |
|
4 |
+
import MedicalTranscription.TranscriptionChunksFixtures
|
5 |
+
|
6 |
alias MedicalTranscription.Coding
|
7 |
alias MedicalTranscription.Coding.CodeVector
|
8 |
alias MedicalTranscription.Feedback.CodeFeedback
|
|
|
36 |
end
|
37 |
|
38 |
describe "process_chunk/2" do
|
39 |
+
@input_text "This 55-year-old man with known coronary artery disease comes for a follow-up visit today."
|
40 |
+
@feedback_text "A 42-year-old man arrived for a return check-up who had a past history of coronary artery disease."
|
41 |
+
|
42 |
setup do
|
43 |
create_code_vector!("74685", "Coronary artery anomaly")
|
44 |
create_code_vector!("41412", "Dissection of coronary artery")
|
|
|
46 |
create_code_vector!("V812", "Screening for other and unspecified cardiovascular conditions")
|
47 |
create_code_vector!("V4589", "Other postprocedural status")
|
48 |
|
49 |
+
input_chunk = transcription_chunk_fixture(%{text: @input_text})
|
50 |
+
feedback_chunk = transcription_chunk_fixture(%{text: @feedback_text})
|
51 |
|
52 |
+
{:ok, input_chunk: input_chunk, feedback_chunk: feedback_chunk}
|
53 |
+
end
|
54 |
|
55 |
+
test "Codes can be weighted multiple times when multiple prior feedback items exist for a single code", %{input_chunk: chunk} do
|
56 |
# One negative feedback item moves the code from 1st to 4th (x0.9).
|
57 |
# The net result of 2 negative and 1 positive (x0.891) is to remove the code from the results.
|
58 |
create_code_feedback!(@feedback_text, false, "74685")
|
59 |
create_code_feedback!(@feedback_text, true, "74685")
|
60 |
create_code_feedback!(@feedback_text, false, "74685")
|
61 |
+
results = Coding.process_chunk(chunk)
|
62 |
|
63 |
assert Enum.map(results, & &1.code) == ["41412", "V717", "V812"]
|
64 |
assert Enum.all?(results, &(&1.weighting == [:none]))
|
65 |
end
|
66 |
|
67 |
+
test "Weighting can cause codes to appear in results that wouldn't have been included from the initial similarity query", %{input_chunk: chunk} do
|
68 |
# E.g. weighting up a code that isn't in the initial results
|
69 |
create_code_feedback!(@feedback_text, true, "V4589")
|
70 |
+
results = Coding.process_chunk(chunk)
|
71 |
|
72 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812", "V4589"]
|
73 |
|
|
|
80 |
]
|
81 |
end
|
82 |
|
83 |
+
test "Codes are unweighted when no prior feedback", %{input_chunk: chunk} do
|
84 |
+
results = Coding.process_chunk(chunk)
|
85 |
|
86 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812"]
|
87 |
assert Enum.all?(results, &(&1.weighting == [:none]))
|
88 |
end
|
89 |
|
90 |
+
test "Code is ranked higher when prior positive feedback", %{input_chunk: chunk} do
|
91 |
create_code_feedback!(@feedback_text, true, "V717")
|
92 |
+
results = Coding.process_chunk(chunk)
|
93 |
|
94 |
assert Enum.map(results, & &1.code) == ["V717", "74685", "41412", "V812"]
|
95 |
assert Enum.map(results, & &1.weighting) == [[:positive], [:none], [:none], [:none]]
|
96 |
end
|
97 |
|
98 |
+
test "Code is ranked lower when prior negative feedback", %{input_chunk: chunk} do
|
99 |
create_code_feedback!(@feedback_text, false, "74685")
|
100 |
+
results = Coding.process_chunk(chunk)
|
101 |
|
102 |
assert Enum.map(results, & &1.code) == ["41412", "V717", "V812", "74685"]
|
103 |
assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none], [:negative]]
|
104 |
end
|
105 |
|
106 |
+
test "Code with low similarity score is removed from result when prior negative feedback", %{input_chunk: chunk} do
|
107 |
create_code_feedback!(@feedback_text, false, "V717")
|
108 |
+
results = Coding.process_chunk(chunk)
|
109 |
|
110 |
assert Enum.map(results, & &1.code) == ["74685", "41412", "V812"]
|
111 |
assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none]]
|
test/medical_transcription_web/live/transcriptions_live_show_test.exs
CHANGED
@@ -25,7 +25,7 @@ defmodule MedicalTranscriptionWeb.TranscriptionsLive.ShowTest do
|
|
25 |
conn = get(conn, "/transcriptions/#{transcription.id}")
|
26 |
assert html_response(conn, 200) =~ "Medical Code Transcriber"
|
27 |
|
28 |
-
{:ok,
|
29 |
assert html =~ "my-audio.mp3"
|
30 |
assert html =~ "Foo"
|
31 |
assert html =~ "Bar"
|
|
|
25 |
conn = get(conn, "/transcriptions/#{transcription.id}")
|
26 |
assert html_response(conn, 200) =~ "Medical Code Transcriber"
|
27 |
|
28 |
+
{:ok, _view, html} = live(conn)
|
29 |
assert html =~ "my-audio.mp3"
|
30 |
assert html =~ "Foo"
|
31 |
assert html =~ "Bar"
|
test/support/fixtures/code_vectors_fixtures.ex
CHANGED
@@ -7,7 +7,7 @@ defmodule MedicalTranscription.CodeVectorsFixtures do
|
|
7 |
@doc """
|
8 |
Insert code vectors from cached csv file.
|
9 |
"""
|
10 |
-
def insert_code_vector_fixtures(
|
11 |
code_vectors =
|
12 |
"../../../code_vectors.csv"
|
13 |
|> Path.expand(__DIR__)
|
|
|
7 |
@doc """
|
8 |
Insert code vectors from cached csv file.
|
9 |
"""
|
10 |
+
def insert_code_vector_fixtures() do
|
11 |
code_vectors =
|
12 |
"../../../code_vectors.csv"
|
13 |
|> Path.expand(__DIR__)
|