Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make percentage input consistent #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions lib/fun_with_flags/ui/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ defmodule FunWithFlags.UI.Router do
flag_name = String.to_existing_atom(name)
type = Utils.parse_percentage_type(conn.params["percent_type"])

case Utils.parse_and_validate_float(conn.params["percent_value"]) do
case Utils.parse_and_validate_float(conn.params["percent_value"], 0..100) do
{:ok, float} ->
FunWithFlags.enable(flag_name, for_percentage_of: {type, float})
FunWithFlags.enable(flag_name, for_percentage_of: {type, float / 100})
redirect_to conn, "/flags/#{name}#percentage_gate"
{:fail, reason} ->
{:ok, flag} = Utils.get_flag(name)
Expand Down
10 changes: 5 additions & 5 deletions lib/fun_with_flags/ui/templates/rows/_percentage_form.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
<input type="hidden" name="_csrf_token" value="<%= @conn.assigns[:csrf_token] %>">
<%= if assigns[:error_message] do %>
<div class="input-group mr-2 has-danger fwf-wide-input">
<div class="input-group-addon">percentage</div>
<div class="input-group-addon"><code>0 < x < 1</code></div>
<input type="number" step="0.000000001" class="form-control form-control-danger" id="percent_value" name="percent_value" placeholder="e.g. 0.421337 for 42.1337%">
<div class="input-group-addon">%</div>
<div class="input-group-addon"><code>0 < x < 100</code></div>
<input type="number" step="0.0000001" class="form-control form-control-danger" id="percent_value" name="percent_value" placeholder="e.g. 42.1337 for 42.1337%">
</div>
<% else %>
<div class="input-group mr-2 fwf-wide-input">
<div class="input-group-addon">%</div>
<div class="input-group-addon"><code>0 < x < 1</code></div>
<input type="number" step="0.000000001" class="form-control" id="percent_value" name="percent_value" placeholder="e.g. 0.421337 for 42.1337%">
<div class="input-group-addon"><code>0 < x < 100</code></div>
<input type="number" step="0.0000001" class="form-control" id="percent_value" name="percent_value" placeholder="e.g. 42.1337 for 42.1337%">
</div>
<% end %>

Expand Down
7 changes: 4 additions & 3 deletions lib/fun_with_flags/ui/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,16 @@ defmodule FunWithFlags.UI.Utils do
end


def parse_and_validate_float(string) do
## Validates the string representation of the float is between 0 and less_than_val, exclusive
def parse_and_validate_float(string, exclusive_min..exclusive_max//1 \\ 0..1//1) do
if blank?(string) do
{:fail, "can't be blank"}
else
case Float.parse(string) do
{float, _} when float > 0 and float < 1 ->
{float, _} when float > exclusive_min and float < exclusive_max ->
{:ok, float}
{_float, _} ->
{:fail, "is outside the '0.0 < x < 1.0' range"}
{:fail, "is outside the '#{exclusive_min} < x < #{exclusive_max}' range"}
:error ->
{:fail, "is not a valid decimal number"}
end
Expand Down
6 changes: 3 additions & 3 deletions test/fun_with_flags/ui/router_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ defmodule FunWithFlags.UI.RouterTest do

conn = request!(:post, "/flags/chocolate/percentage", %{
percent_type: "time",
percent_value: "0.5"
percent_value: "50"
})
assert 302 = conn.status
assert ["/flags/chocolate#percentage_gate"] = get_resp_header(conn, "location")
Expand All @@ -172,14 +172,14 @@ defmodule FunWithFlags.UI.RouterTest do

conn = request!(:post, "/flags/chocolate/percentage", %{
percent_type: "time",
percent_value: "0.5"
percent_value: "25.5"
})
assert 302 = conn.status
assert ["/flags/chocolate#percentage_gate"] = get_resp_header(conn, "location")

assert %Flag{name: :chocolate, gates: [
%Gate{type: :boolean},
%Gate{type: :percentage_of_time, for: 0.5},
%Gate{type: :percentage_of_time, for: 0.255},
]} = FunWithFlags.get_flag(:chocolate)
end

Expand Down
31 changes: 21 additions & 10 deletions test/fun_with_flags/ui/utils_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,15 @@ defmodule FunWithFlags.UI.UtilsTest do
end

test "it rejects floats smaller than equal to 0 or larger than or equal to 1" do
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("0")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("0.0")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("1")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("1.0")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("-2")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("11")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("-2.5")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("-0.01")
assert {:fail, "is outside the '0.0 < x < 1.0' range"} = Utils.parse_and_validate_float("1.01")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("0")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("0.0")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("1")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("1.0")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("-2")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("11")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("-2.5")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("-0.01")
assert {:fail, "is outside the '0 < x < 1' range"} = Utils.parse_and_validate_float("1.01")
end

test "it parses and returns valid floats" do
Expand All @@ -254,8 +254,19 @@ defmodule FunWithFlags.UI.UtilsTest do
assert {:ok, 0.999999999} = Utils.parse_and_validate_float("0.999999999")
assert {:ok, 0.54} = Utils.parse_and_validate_float("0.54")
end
end

test "supports other ranges" do
assert {:ok, -9.2} = Utils.parse_and_validate_float("-9.2", -10..10)

assert {:fail, "is outside the '-10 < x < 10' range"} =
Utils.parse_and_validate_float("-10.1", -10..10)

assert {:ok, 10.2} = Utils.parse_and_validate_float("10.2", 10..11)

assert {:fail, "is outside the '10 < x < 11' range"} =
Utils.parse_and_validate_float("11.1", 10..11)
end
end

describe "parse_percentage_type(string)" do
test "it parses and symbolizes the known types" do
Expand Down