feat(medicine): support voluntary pharmacy purchase
This commit is contained in:
parent
51de2d829b
commit
144167beae
17
README.md
17
README.md
|
|
@ -1,14 +1,17 @@
|
||||||
# Who Need Help
|
# Who Need Help
|
||||||
|
|
||||||
Who Need Help is a working mutual-aid MVP for urgent, local, voluntary help.
|
Who Need Help is a working mutual-aid MVP for urgent, local, voluntary help.
|
||||||
The first priority is pickup and delivery of a legal medicine that has already
|
The first priority is asking whether a nearby volunteer is willing to purchase,
|
||||||
been purchased or reserved. The same urgent-help flow also supports safe,
|
pick up, and deliver lawful medicine. Accepting never obliges a helper to spend
|
||||||
non-emergency fuel delivery, wheel help, bicycle and motorcycle problems,
|
money; purchase and reimbursement arrangements remain directly between the
|
||||||
vehicle breakdowns, and practical support after a secured road incident.
|
matched people. The same urgent-help flow also supports safe, non-emergency fuel
|
||||||
|
delivery, wheel help, bicycle and motorcycle problems, vehicle breakdowns, and
|
||||||
|
practical support after a secured road incident.
|
||||||
|
|
||||||
It is not an emergency or medical service, does not prescribe or sell medicine,
|
It is not an emergency, medical, pharmacy, or payment service, does not
|
||||||
and does not process payments. A helper may publish an optional external
|
prescribe or sell medicine, and does not guarantee reimbursement. A helper may
|
||||||
thank-you link; money goes directly between users outside the platform.
|
publish an optional external thank-you link; money goes directly between users
|
||||||
|
outside the platform.
|
||||||
|
|
||||||
## OpenAI Build Week 2026
|
## OpenAI Build Week 2026
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ Status: MVP specification for OpenAI Build Week, 2026-07-18.
|
||||||
Who Need Help connects an adult who needs urgent, practical nearby help with an
|
Who Need Help connects an adult who needs urgent, practical nearby help with an
|
||||||
adult volunteer who can provide it without a mandatory fee.
|
adult volunteer who can provide it without a mandatory fee.
|
||||||
|
|
||||||
The first-priority scenario lets a requester ask a nearby person to pick up and
|
The first-priority scenario lets a requester ask whether a nearby person is
|
||||||
deliver medication that has already been legally purchased or reserved. The
|
willing to purchase, pick up, and deliver lawful medicine. The urgent-help mode
|
||||||
urgent-help mode also covers non-emergency roadside tasks after people and
|
also covers non-emergency roadside tasks after people and vehicles are away from
|
||||||
vehicles are away from active danger. The product does not diagnose, prescribe,
|
active danger. The product does not diagnose, prescribe, recommend, sell,
|
||||||
recommend, sell, reimburse, or handle controlled substances.
|
process payment, guarantee reimbursement, or handle controlled substances.
|
||||||
|
|
||||||
## Primary user journey
|
## Primary user journey
|
||||||
|
|
||||||
|
|
@ -71,8 +71,8 @@ helper per request. Every state transition is authorized and recorded.
|
||||||
|
|
||||||
## Explicitly outside the MVP
|
## Explicitly outside the MVP
|
||||||
|
|
||||||
- Medical advice, prescriptions, pharmacy integrations, medication sale, and
|
- Medical advice, pharmacy integrations, medication sale, platform payment or
|
||||||
controlled-substance delivery.
|
reimbursement, and controlled-substance delivery.
|
||||||
- Platform payments, escrow, fees, or compulsory compensation.
|
- Platform payments, escrow, fees, or compulsory compensation.
|
||||||
- Background PWA or unattended location tracking.
|
- Background PWA or unattended location tracking.
|
||||||
- Multiple simultaneous helpers on one request.
|
- Multiple simultaneous helpers on one request.
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,14 @@ Who Need Help is a coordination tool for adults. It is not an emergency service.
|
||||||
Every urgent screen must tell users to contact local emergency services when
|
Every urgent screen must tell users to contact local emergency services when
|
||||||
life, health, fire, violence, or immediate danger is involved.
|
life, health, fire, violence, or immediate danger is involved.
|
||||||
|
|
||||||
The medicine category is limited to pickup/delivery of an already purchased or
|
The medicine category permits a requester to ask whether a volunteer is willing
|
||||||
reserved legal item. Requests for medical advice, prescriptions, cash advances,
|
to purchase, pick up, and deliver a lawful medicine. Accepting a request never
|
||||||
controlled substances, or suspicious repackaging are reportable and removable.
|
obliges a volunteer to spend money. The matched people arrange pharmacy or
|
||||||
|
prescription requirements, payment, reimbursement, storage, and handover
|
||||||
|
directly in private chat. The platform does not prescribe, recommend, sell,
|
||||||
|
process payment, extend credit, or guarantee reimbursement. Requests for medical
|
||||||
|
advice, controlled substances, unlawful supply, payment credentials, public
|
||||||
|
prescription disclosure, or suspicious repackaging are reportable and removable.
|
||||||
|
|
||||||
Social activities are a separate product mode. They do not use handover codes,
|
Social activities are a separate product mode. They do not use handover codes,
|
||||||
helper reviews, live movement evidence, or the helper leaderboard. The
|
helper reviews, live movement evidence, or the helper leaderboard. The
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,7 @@ defmodule WhoNeedHelp.Catalog do
|
||||||
is_nil(category.parent_id) and not is_nil(attrs[:parent_id]),
|
is_nil(category.parent_id) and not is_nil(attrs[:parent_id]),
|
||||||
attrs[:parent_id]
|
attrs[:parent_id]
|
||||||
)
|
)
|
||||||
|
|> refresh_core_category(category, attrs)
|
||||||
|
|
||||||
if map_size(backfill) == 0 do
|
if map_size(backfill) == 0 do
|
||||||
category
|
category
|
||||||
|
|
@ -406,6 +407,62 @@ defmodule WhoNeedHelp.Catalog do
|
||||||
defp put_backfill(attrs, _key, false, _value), do: attrs
|
defp put_backfill(attrs, _key, false, _value), do: attrs
|
||||||
defp put_backfill(attrs, key, true, value), do: Map.put(attrs, key, value)
|
defp put_backfill(attrs, key, true, value), do: Map.put(attrs, key, value)
|
||||||
|
|
||||||
|
defp refresh_core_category(attrs, %Category{slug: "medicine-pickup"} = category, defaults) do
|
||||||
|
descriptions = Map.merge(category.descriptions || %{}, defaults.descriptions)
|
||||||
|
|
||||||
|
structured_fields =
|
||||||
|
merge_seeded_structured_fields(category.structured_fields, defaults.structured_fields)
|
||||||
|
|
||||||
|
attrs
|
||||||
|
|> put_changed(:descriptions, category.descriptions, descriptions)
|
||||||
|
|> put_changed(:structured_fields, category.structured_fields, structured_fields)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp refresh_core_category(attrs, _category, _defaults), do: attrs
|
||||||
|
|
||||||
|
defp put_changed(attrs, _key, current, current), do: attrs
|
||||||
|
defp put_changed(attrs, key, _current, updated), do: Map.put(attrs, key, updated)
|
||||||
|
|
||||||
|
defp merge_seeded_structured_fields(current, defaults) do
|
||||||
|
current = current || %{}
|
||||||
|
defaults = defaults || %{}
|
||||||
|
current_fields = current["fields"] || []
|
||||||
|
default_fields = defaults["fields"] || []
|
||||||
|
current_by_key = Map.new(current_fields, &{&1["key"], &1})
|
||||||
|
default_keys = MapSet.new(default_fields, & &1["key"])
|
||||||
|
|
||||||
|
merged_defaults =
|
||||||
|
Enum.map(default_fields, fn default_field ->
|
||||||
|
case current_by_key[default_field["key"]] do
|
||||||
|
nil ->
|
||||||
|
default_field
|
||||||
|
|
||||||
|
current_field ->
|
||||||
|
current_field
|
||||||
|
|> Map.merge(default_field)
|
||||||
|
|> Map.put(
|
||||||
|
"options",
|
||||||
|
merge_seeded_options(current_field["options"], default_field["options"])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
custom_fields =
|
||||||
|
Enum.reject(current_fields, &MapSet.member?(default_keys, &1["key"]))
|
||||||
|
|
||||||
|
current
|
||||||
|
|> Map.merge(defaults)
|
||||||
|
|> Map.put("fields", merged_defaults ++ custom_fields)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp merge_seeded_options(current, defaults) when is_list(defaults) do
|
||||||
|
current = if is_list(current), do: current, else: []
|
||||||
|
default_values = MapSet.new(defaults, & &1["value"])
|
||||||
|
defaults ++ Enum.reject(current, &MapSet.member?(default_values, &1["value"]))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp merge_seeded_options(current, _defaults), do: current
|
||||||
|
|
||||||
defp normalize_proposal_mode(attrs) do
|
defp normalize_proposal_mode(attrs) do
|
||||||
attrs = Map.new(attrs, fn {key, value} -> {to_string(key), value} end)
|
attrs = Map.new(attrs, fn {key, value} -> {to_string(key), value} end)
|
||||||
|
|
||||||
|
|
@ -445,9 +502,9 @@ defmodule WhoNeedHelp.Catalog do
|
||||||
names: names("Medicine pickup", "Доставка ліків", "Доставка лекарств"),
|
names: names("Medicine pickup", "Доставка ліків", "Доставка лекарств"),
|
||||||
descriptions:
|
descriptions:
|
||||||
names(
|
names(
|
||||||
"Pickup and deliver a legal medicine that is already purchased or reserved.",
|
"Buy, pick up, and deliver legal medicine when a volunteer freely agrees.",
|
||||||
"Отримати й доставити дозволені ліки, які вже придбані або зарезервовані.",
|
"Придбати, отримати й доставити дозволені ліки, якщо волонтер добровільно погодиться.",
|
||||||
"Получить и доставить разрешённое лекарство, которое уже куплено или зарезервировано."
|
"Купить, получить и доставить разрешённое лекарство, если волонтёр добровольно согласится."
|
||||||
),
|
),
|
||||||
sort_order: 10,
|
sort_order: 10,
|
||||||
structured_fields: %{
|
structured_fields: %{
|
||||||
|
|
@ -460,7 +517,22 @@ defmodule WhoNeedHelp.Catalog do
|
||||||
"Статус получения лекарства"
|
"Статус получения лекарства"
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
option("reserved", names("Reserved", "Зарезервовано", "Зарезервировано")),
|
option(
|
||||||
|
"purchase_needed",
|
||||||
|
names(
|
||||||
|
"Needs to be purchased — only if the volunteer agrees",
|
||||||
|
"Потрібно придбати — лише за згодою волонтера",
|
||||||
|
"Нужно купить — только с согласия волонтёра"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
option(
|
||||||
|
"reserved",
|
||||||
|
names(
|
||||||
|
"Reserved — payment may still be needed",
|
||||||
|
"Зарезервовано — може знадобитися оплата",
|
||||||
|
"Зарезервировано — может потребоваться оплата"
|
||||||
|
)
|
||||||
|
),
|
||||||
option("already_paid", names("Already paid", "Вже оплачено", "Уже оплачено"))
|
option("already_paid", names("Already paid", "Вже оплачено", "Уже оплачено"))
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
<p class="mt-6 max-w-2xl text-lg leading-8 text-base-content/70">
|
<p class="mt-6 max-w-2xl text-lg leading-8 text-base-content/70">
|
||||||
{gettext(
|
{gettext(
|
||||||
"Ask a nearby volunteer to collect medicine that is already purchased or help with a safe roadside problem. There is no mandatory fee."
|
"Ask a nearby volunteer to buy or collect medicine if they agree, or help with a safe roadside problem. There is no mandatory fee."
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-8 flex flex-wrap gap-3">
|
<div class="mt-8 flex flex-wrap gap-3">
|
||||||
|
|
@ -110,7 +110,9 @@
|
||||||
<.icon name="hero-shopping-bag" class="size-7 text-success" />
|
<.icon name="hero-shopping-bag" class="size-7 text-success" />
|
||||||
<h3 class="mt-5 font-bold">{gettext("Collect medicine")}</h3>
|
<h3 class="mt-5 font-bold">{gettext("Collect medicine")}</h3>
|
||||||
<p class="mt-2 text-sm text-base-content/65">
|
<p class="mt-2 text-sm text-base-content/65">
|
||||||
{gettext("The medicine is already legally purchased or reserved for pickup.")}
|
{gettext(
|
||||||
|
"The requester states whether the medicine is paid, reserved, or still needs to be purchased."
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="help-card rounded-3xl border border-base-300 bg-base-100 p-6">
|
<article class="help-card rounded-3xl border border-base-300 bg-base-100 p-6">
|
||||||
|
|
@ -361,7 +363,7 @@
|
||||||
</summary>
|
</summary>
|
||||||
<p class="mt-3 text-sm leading-6 text-base-content/65">
|
<p class="mt-3 text-sm leading-6 text-base-content/65">
|
||||||
{gettext(
|
{gettext(
|
||||||
"The medicine must already be legally purchased or reserved. The service does not prescribe, recommend, sell, or handle controlled substances."
|
"Yes, if the volunteer explicitly agrees. The people arrange the medicine, pharmacy requirements, payment, and any reimbursement directly. The service does not prescribe, recommend, sell medicine, process payments, or guarantee reimbursement."
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<h2 class="text-xl font-bold">{gettext("Medicine requests")}</h2>
|
<h2 class="text-xl font-bold">{gettext("Medicine requests")}</h2>
|
||||||
<p class="mt-2 text-sm leading-6">
|
<p class="mt-2 text-sm leading-6">
|
||||||
{gettext(
|
{gettext(
|
||||||
"Only request pickup of a legal item already reserved or paid for. Do not request medical advice, a prescription, controlled substances, cash advances, repackaging, or a purchase on your behalf. Follow pharmacy rules and local law."
|
"Request only lawful purchase or pickup from a legitimate pharmacy. A volunteer is never required to pay. Agree privately on the medicine, pharmacy or prescription requirements, payment, reimbursement, storage, and handover. Who Need Help does not prescribe, recommend, sell medicine, process payments, or guarantee reimbursement. Do not request controlled substances or publish prescriptions or payment credentials. Follow pharmacy rules and local law."
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,18 @@
|
||||||
<p class="mt-3">
|
<p class="mt-3">
|
||||||
Follow applicable law, pharmacy and venue rules, the Safety Rules, and other people's
|
Follow applicable law, pharmacy and venue rules, the Safety Rules, and other people's
|
||||||
consent and privacy. Do not request or provide unlawful goods or services, medical
|
consent and privacy. Do not request or provide unlawful goods or services, medical
|
||||||
advice, prescriptions, controlled substances, cash advances, harassment, threats,
|
advice, controlled substances, cash advances, harassment, threats,
|
||||||
impersonation, fraud, spam, sexual exploitation, non-consensual intimate material,
|
impersonation, fraud, spam, sexual exploitation, non-consensual intimate material,
|
||||||
instructions for wrongdoing, or content that violates another person's rights. Do not
|
instructions for wrongdoing, or content that violates another person's rights. Do not
|
||||||
manipulate matches, evidence, reviews, votes, tracking, or reputation.
|
manipulate matches, evidence, reviews, votes, tracking, or reputation.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="mt-3">
|
||||||
|
A requester may ask whether a volunteer is willing to purchase lawful medicine. Accepting
|
||||||
|
a request never obliges a volunteer to spend money. The people involved arrange pharmacy
|
||||||
|
or prescription requirements, payment, reimbursement, storage, and handover directly and
|
||||||
|
at their own risk. Who Need Help does not sell medicine, process payment, extend credit,
|
||||||
|
guarantee reimbursement, or override pharmacy rules or applicable law.
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section aria-labelledby="terms-content">
|
<section aria-labelledby="terms-content">
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@
|
||||||
|
|
||||||
<p class="my-4 text-xs text-base-content/60">
|
<p class="my-4 text-xs text-base-content/60">
|
||||||
{gettext(
|
{gettext(
|
||||||
"Who Need Help is not an emergency or medical service. Medicine requests are limited to pickup of legal items already purchased or reserved."
|
"Who Need Help is not an emergency, medical, pharmacy, or payment service. A volunteer may agree to buy or collect lawful medicine, but is never required to spend money."
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do
|
||||||
do: WhoNeedHelp.Catalog.Category.description(category, locale)
|
do: WhoNeedHelp.Catalog.Category.description(category, locale)
|
||||||
|
|
||||||
defp category_title_placeholder(%{slug: "medicine-pickup"}),
|
defp category_title_placeholder(%{slug: "medicine-pickup"}),
|
||||||
do: gettext("Medicine is ready at the pharmacy")
|
do: gettext("Medicine is needed from a pharmacy")
|
||||||
|
|
||||||
defp category_title_placeholder(%{parent: %{slug: "roadside-help"}}),
|
defp category_title_placeholder(%{parent: %{slug: "roadside-help"}}),
|
||||||
do: gettext("Need roadside help in a safe location")
|
do: gettext("Need roadside help in a safe location")
|
||||||
|
|
@ -215,7 +215,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do
|
||||||
|
|
||||||
defp safety_confirmation(%{slug: "medicine-pickup"}) do
|
defp safety_confirmation(%{slug: "medicine-pickup"}) do
|
||||||
gettext(
|
gettext(
|
||||||
"I confirm this is not an emergency, medical advice request, controlled substance, or request to buy medicine on my behalf."
|
"I confirm this is not an emergency or request for medical advice, the medicine and arrangement are lawful, and a volunteer chooses whether to spend money."
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -368,6 +368,15 @@ defmodule WhoNeedHelpWeb.RequestLive.New do
|
||||||
>
|
>
|
||||||
{message}
|
{message}
|
||||||
</p>
|
</p>
|
||||||
|
<p
|
||||||
|
:if={@selected_category && @selected_category.slug == "medicine-pickup"}
|
||||||
|
id="medicine-purchase-guidance"
|
||||||
|
class="rounded-xl bg-base-100/80 p-3 text-sm leading-6 text-base-content/70"
|
||||||
|
>
|
||||||
|
{gettext(
|
||||||
|
"If purchase is needed, accepting the request does not require the volunteer to spend money. Agree on the medicine, pharmacy requirements, payment, and any reimbursement only in the private matched chat."
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<.input
|
<.input
|
||||||
field={@form[:title]}
|
field={@form[:title]}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
57
test/who_need_help/catalog_test.exs
Normal file
57
test/who_need_help/catalog_test.exs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
defmodule WhoNeedHelp.CatalogTest do
|
||||||
|
use WhoNeedHelp.DataCase, async: false
|
||||||
|
|
||||||
|
alias WhoNeedHelp.Catalog
|
||||||
|
alias WhoNeedHelp.Catalog.Category
|
||||||
|
|
||||||
|
test "medicine defaults support voluntary purchase and upgrade an existing category" do
|
||||||
|
category = Catalog.seed_defaults()
|
||||||
|
|
||||||
|
old_structured_fields = %{
|
||||||
|
"fields" => [
|
||||||
|
%{
|
||||||
|
"key" => "pickup_status",
|
||||||
|
"type" => "select",
|
||||||
|
"required" => true,
|
||||||
|
"label" => %{"en" => "Medicine pickup status"},
|
||||||
|
"options" => [
|
||||||
|
%{"value" => "reserved", "label" => %{"en" => "Reserved"}},
|
||||||
|
%{"value" => "already_paid", "label" => %{"en" => "Already paid"}}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"key" => "community_note",
|
||||||
|
"type" => "text",
|
||||||
|
"required" => false,
|
||||||
|
"label" => %{"en" => "Community note"},
|
||||||
|
"max_length" => 80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
category
|
||||||
|
|> Category.changeset(%{
|
||||||
|
descriptions: %{"en" => "Old pickup-only description"},
|
||||||
|
structured_fields: old_structured_fields
|
||||||
|
})
|
||||||
|
|> Repo.update!()
|
||||||
|
|
||||||
|
upgraded = Catalog.seed_defaults()
|
||||||
|
fields = Catalog.structured_fields(upgraded)
|
||||||
|
pickup_status = Enum.find(fields, &(&1["key"] == "pickup_status"))
|
||||||
|
|
||||||
|
assert Enum.map(pickup_status["options"], & &1["value"]) == [
|
||||||
|
"purchase_needed",
|
||||||
|
"reserved",
|
||||||
|
"already_paid"
|
||||||
|
]
|
||||||
|
|
||||||
|
assert Enum.any?(fields, &(&1["key"] == "community_note"))
|
||||||
|
assert upgraded.descriptions["en"] =~ "freely agrees"
|
||||||
|
|
||||||
|
assert {:ok, %{"pickup_status" => "purchase_needed"}} =
|
||||||
|
Catalog.validate_structured_data(upgraded, %{
|
||||||
|
"pickup_status" => "purchase_needed"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -393,8 +393,11 @@ defmodule WhoNeedHelpWeb.MutualAidLiveTest do
|
||||||
})
|
})
|
||||||
|
|
||||||
assert html =~ "Medicine pickup status"
|
assert html =~ "Medicine pickup status"
|
||||||
assert html =~ "Pickup and deliver a legal medicine"
|
assert html =~ "Buy, pick up, and deliver legal medicine"
|
||||||
|
assert html =~ "Needs to be purchased"
|
||||||
|
assert html =~ "accepting the request does not require the volunteer to spend money"
|
||||||
assert html =~ "help_request[structured_data][pickup_status]"
|
assert html =~ "help_request[structured_data][pickup_status]"
|
||||||
|
assert has_element?(view, "#medicine-purchase-guidance")
|
||||||
refute html =~ "Medicine pickup status is required."
|
refute html =~ "Medicine pickup status is required."
|
||||||
refute html =~ "pickup_status is required"
|
refute html =~ "pickup_status is required"
|
||||||
|
|
||||||
|
|
@ -434,7 +437,8 @@ defmodule WhoNeedHelpWeb.MutualAidLiveTest do
|
||||||
"help_request" => %{"category_id" => category.id}
|
"help_request" => %{"category_id" => category.id}
|
||||||
})
|
})
|
||||||
|
|
||||||
assert html =~ "Отримати й доставити дозволені ліки"
|
assert html =~ "Придбати, отримати й доставити дозволені ліки"
|
||||||
|
assert html =~ "Потрібно придбати"
|
||||||
|
|
||||||
html =
|
html =
|
||||||
render_change(view, "validate", %{
|
render_change(view, "validate", %{
|
||||||
|
|
@ -662,6 +666,7 @@ defmodule WhoNeedHelpWeb.MutualAidLiveTest do
|
||||||
{:ok, activity} = Activities.create_activity(organizer_scope, attrs)
|
{:ok, activity} = Activities.create_activity(organizer_scope, attrs)
|
||||||
{:ok, organizer_view, _html} = live(organizer_conn, ~p"/activities/#{activity.id}")
|
{:ok, organizer_view, _html} = live(organizer_conn, ~p"/activities/#{activity.id}")
|
||||||
{:ok, participant_view, html} = live(participant_conn, ~p"/activities/#{activity.id}")
|
{:ok, participant_view, html} = live(participant_conn, ~p"/activities/#{activity.id}")
|
||||||
|
|
||||||
assert has_element?(
|
assert has_element?(
|
||||||
participant_view,
|
participant_view,
|
||||||
"#activity-detail-map[data-map-recenter-label='Show location on map']"
|
"#activity-detail-map[data-map-recenter-label='Show location on map']"
|
||||||
|
|
@ -789,7 +794,11 @@ defmodule WhoNeedHelpWeb.MutualAidLiveTest do
|
||||||
{:ok, request} = Help.create_request(requester_scope, request_attrs(category))
|
{:ok, request} = Help.create_request(requester_scope, request_attrs(category))
|
||||||
{:ok, requester_view, _html} = live(requester_conn, ~p"/requests/#{request.id}")
|
{:ok, requester_view, _html} = live(requester_conn, ~p"/requests/#{request.id}")
|
||||||
{:ok, helper_view, _html} = live(helper_conn, ~p"/requests/#{request.id}")
|
{:ok, helper_view, _html} = live(helper_conn, ~p"/requests/#{request.id}")
|
||||||
assert has_element?(requester_view, "#show-map[data-map-recenter-label='Show location on map']")
|
|
||||||
|
assert has_element?(
|
||||||
|
requester_view,
|
||||||
|
"#show-map[data-map-recenter-label='Show location on map']"
|
||||||
|
)
|
||||||
|
|
||||||
helper_view
|
helper_view
|
||||||
|> element("button[phx-click='accept']")
|
|> element("button[phx-click='accept']")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user