Prohlížeč zdrojového kódu
spec/services/source_browser_spec.rb
require "rails_helper"
RSpec.describe SourceBrowser do
before { SourceBrowser.reload! }
describe ".list" do
it "returns top-level entries" do
entries = SourceBrowser.list
names = entries.map { |e| e[:name] }
expect(names).to include("app")
expect(names).to include("config")
expect(names).to include("spec")
end
it "returns entries for a subdirectory" do
entries = SourceBrowser.list("app")
names = entries.map { |e| e[:name] }
expect(names).to include("controllers")
expect(names).to include("services")
expect(names).to include("assets")
expect(names).to include("javascript")
end
it "marks directories and files correctly" do
entries = SourceBrowser.list("app/services")
dirs = entries.select { |e| e[:directory] }
files = entries.reject { |e| e[:directory] }
expect(files.map { |e| e[:name] }).to include("example_registry.rb")
expect(dirs).to be_empty # services has no subdirs in whitelist
end
end
describe ".read" do
it "reads whitelisted files" do
content = SourceBrowser.read("config/routes.rb")
expect(content).to include("Rails.application.routes.draw")
end
it "reads Gemfile" do
content = SourceBrowser.read("Gemfile")
expect(content).to include("rails")
end
it "reads spec files" do
content = SourceBrowser.read("spec/rails_helper.rb")
expect(content).to include("RSpec")
end
it "reads stylesheets" do
content = SourceBrowser.read("app/assets/stylesheets/application.scss")
expect(content).to be_present
end
it "reads javascript files" do
content = SourceBrowser.read("app/javascript/application.js")
expect(content).to be_present
end
end
describe "security" do
it "rejects path traversal with .." do
expect { SourceBrowser.read("../../etc/passwd") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects null bytes" do
expect { SourceBrowser.read("config/routes.rb\0.txt") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects files not in whitelist" do
expect { SourceBrowser.read("config/database.yml") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects path traversal in list" do
expect { SourceBrowser.list("../..") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects null bytes in list" do
expect { SourceBrowser.list("app\0/etc") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects path traversal in full_path" do
expect { SourceBrowser.full_path("../../etc/passwd") }
.to raise_error(SourceBrowser::NotAllowed)
end
it "rejects non-whitelisted path in full_path" do
expect { SourceBrowser.full_path("config/database.yml") }
.to raise_error(SourceBrowser::NotAllowed)
end
end
describe ".file?" do
it "returns true for whitelisted files" do
expect(SourceBrowser.file?("config/routes.rb")).to be true
end
it "returns false for non-whitelisted files" do
expect(SourceBrowser.file?("config/database.yml")).to be false
end
it "returns true for spec files" do
expect(SourceBrowser.file?("spec/rails_helper.rb")).to be true
end
it "returns true for stylesheets" do
expect(SourceBrowser.file?("app/assets/stylesheets/application.scss")).to be true
end
end
describe ".binary?" do
it "returns true for image files" do
expect(SourceBrowser.binary?("app/assets/images/logo.png")).to be true
expect(SourceBrowser.binary?("app/assets/images/photo.jpg")).to be true
expect(SourceBrowser.binary?("app/assets/images/icon.ico")).to be true
end
it "returns true for font files" do
expect(SourceBrowser.binary?("app/assets/fonts/font.woff2")).to be true
expect(SourceBrowser.binary?("app/assets/fonts/font.ttf")).to be true
end
it "returns false for text files" do
expect(SourceBrowser.binary?("app/assets/stylesheets/application.scss")).to be false
expect(SourceBrowser.binary?("config/routes.rb")).to be false
expect(SourceBrowser.binary?("app/javascript/application.js")).to be false
end
end
describe ".full_path" do
it "returns the absolute path for a whitelisted file" do
path = SourceBrowser.full_path("config/routes.rb")
expect(path).to eq(Rails.root.join("config/routes.rb").to_s)
expect(File.file?(path)).to be true
end
end
describe ".tree" do
it "flags binary files" do
tree = SourceBrowser.tree
all_files = []
collect = ->(node) {
all_files.concat(node[:files])
node[:dirs].each_value { |d| collect.call(d) }
}
collect.call(tree)
rb_file = all_files.find { |f| f[:name].end_with?(".rb") }
expect(rb_file[:binary]).to be false
end
end
describe ".language_for" do
it "detects Ruby" do
expect(SourceBrowser.language_for("foo.rb")).to eq("ruby")
end
it "detects ERB" do
expect(SourceBrowser.language_for("foo.html.erb")).to eq("erb")
end
it "detects YAML" do
expect(SourceBrowser.language_for("foo.yml")).to eq("yaml")
end
it "detects SCSS" do
expect(SourceBrowser.language_for("foo.scss")).to eq("scss")
end
it "detects CSS" do
expect(SourceBrowser.language_for("pico.min.css")).to eq("css")
end
it "detects JavaScript" do
expect(SourceBrowser.language_for("application.js")).to eq("javascript")
end
it "detects Gemfile as Ruby" do
expect(SourceBrowser.language_for("Gemfile")).to eq("ruby")
end
it "defaults to plaintext" do
expect(SourceBrowser.language_for("Dockerfile")).to eq("plaintext")
end
end
end