discourse-data-explorer/spec/lib/parameter_spec.rb
锦心 1d991c6192
FIX: fix double validation (#314)
The old float validation had several bugs. It will recognize strings
like "a1.2" and "3.4b" as valid doubles, but will not recognize integers
like "1234" as doubles. Also, since an empty string is not falsy in Ruby,
it will recognize "Inf" as -Infinity.

This commit fixes these issues
2024-08-21 15:39:56 +08:00

136 lines
4.8 KiB
Ruby

# frozen_string_literal: true
RSpec.describe DiscourseDataExplorer::Parameter do
def param(identifier, type, default, nullable)
described_class.new(identifier, type, default, nullable)
end
describe ".cast_to_ruby" do
it "returns nil for nullable blank string" do
expect(param("param123", :string, nil, true).cast_to_ruby("")).to eq(nil)
end
it "raises error for not-nullable blank string" do
expect { param("param123", :string, nil, false).cast_to_ruby("") }.to raise_error(
::DiscourseDataExplorer::ValidationError,
)
end
describe "double type" do
let!(:double_param) { param("double", :double, nil, false) }
it "raises an error if not a double" do
expect { double_param.cast_to_ruby("abcd") }.to raise_error(
::DiscourseDataExplorer::ValidationError,
)
end
it "returns the float number if it can be a valid double" do
expect(double_param.cast_to_ruby("3.14")).to eq(3.14)
expect(double_param.cast_to_ruby(".314")).to eq(0.314)
expect(double_param.cast_to_ruby("1")).to eq(1.0)
expect(double_param.cast_to_ruby("Inf")).to eq(Float::INFINITY)
expect(double_param.cast_to_ruby("-Infinity")).to eq(-Float::INFINITY)
expect(double_param.cast_to_ruby("-NaN").nan?).to eq(true)
expect(double_param.cast_to_ruby("NaN").nan?).to eq(true)
end
end
describe "post_id type" do
fab!(:post)
context "when the value provided is a post share URL" do
it "returns the found post id" do
expect(param("post_id", :post_id, nil, false).cast_to_ruby(post.url)).to eq(post.id)
end
it "returns the found post id when there is a share user param" do
expect(
param("post_id", :post_id, nil, false).cast_to_ruby(
"#{post.url}?u=#{post.user.username}",
),
).to eq(post.id)
end
it "returns the found post id when no post number is provided" do
expect(
param("post_id", :post_id, nil, false).cast_to_ruby("#{post.url(share_url: true)}"),
).to eq(post.id)
end
it "raises an error if no such post exists" do
post.destroy
expect { param("post_id", :post_id, nil, false).cast_to_ruby(post.url) }.to raise_error(
::DiscourseDataExplorer::ValidationError,
)
end
end
context "when the value provided is an integer" do
it "raises an error if no such post exists" do
expect { param("post_id", :post_id, nil, false).cast_to_ruby("-999") }.to raise_error(
::DiscourseDataExplorer::ValidationError,
)
end
it "returns the post id if the post exists" do
expect(param("post_id", :post_id, nil, false).cast_to_ruby(post.id.to_s)).to eq(post.id)
end
end
end
describe "group_id type" do
fab!(:group)
context "when the value provided is an integer" do
it "raises an error if no such group exists" do
expect { param("group_id", :group_id, nil, false).cast_to_ruby("-999") }.to raise_error(
::DiscourseDataExplorer::ValidationError,
)
end
it "returns the group id if the group exists" do
expect(param("group_id", :group_id, nil, false).cast_to_ruby(group.id.to_s)).to eq(
group.id,
)
end
end
end
describe "user_id type" do
fab!(:user)
it "raises an error if no such user exists" do
expect {
param("user_id", :user_id, nil, false).cast_to_ruby("user_not_exist")
}.to raise_error(::DiscourseDataExplorer::ValidationError)
expect {
param("user_id", :user_id, nil, false).cast_to_ruby("user_not_exist@fake.email")
}.to raise_error(::DiscourseDataExplorer::ValidationError)
end
it "returns the user id if the user exists" do
expect(param("user_id", :user_id, nil, false).cast_to_ruby(user.username)).to eq(user.id)
expect(param("user_id", :user_id, nil, false).cast_to_ruby(user.email)).to eq(user.id)
end
end
end
describe ".create_from_sql" do
it "should not validate default value" do
TEST_SQL = <<~SQL
-- [params]
-- user_id :user_id = user_not_exists
-- post_id :post_id = /t/should-not-exist/33554432/1
-- topic_id :topic_id = /t/should-not-exist/2147483646
-- category_id :category_id = category_not_exists
-- group_id :group_id = group_not_exists
-- group_list :group_list = group_not_exists1,group_not_exists1
-- user_list :mul_users = user_not_exists1,user_not_exists2
SELECT 1
SQL
expect(described_class.create_from_sql(TEST_SQL).length).to eq(7)
end
end
end