Add a persisted test suite
`bundle exec rake test` (minitest, a default gem but pinned in Gemfile for reproducibility) now covers what ad-hoc scripts kept re-verifying by hand during development: Gpx/Fit/TrackStats parsing, GpxStore/LiveTrackStore file/TTL logic, LiveTrackClient's payload parsing, and app.rb's routes end to end via Rack::MockRequest. MAPTOOL_DATA_DIR (new, app.rb) lets the suite point GPX_STORE/ LIVETRACK_STORE at a throwaway directory instead of real data/ — without it every run would leave uploaded test files behind. Each lib file's old `if __FILE__ == $0` self-check is now redundant with real tests covering the same ground, so removed rather than kept as a second copy of the same assertions. Wired into ci.yml so it isn't just a local convenience.
This commit is contained in:
1 parent
a3c31ace06
commit
cd4eef342b
19 files changed
+706
-174
No files matched your search
@@ -0,0 +1,70 @@
|
||||
require_relative "test_helper"
|
||||
require "maptool/gpx_store"
|
||||
require "stringio"
|
||||
|
||||
class GpxStoreTest < Minitest::Test
|
||||
def setup
|
||||
@store = Maptool::GpxStore.new(Dir.mktmpdir)
|
||||
end
|
||||
|
||||
def test_save_returns_the_relative_path_and_lists_it_in_the_tree
|
||||
path = @store.save(folder: "", filename: "ride.gpx", io: StringIO.new("<gpx></gpx>"))
|
||||
|
||||
assert_equal "ride.gpx", path
|
||||
assert_equal ["ride.gpx"], @store.tree["children"].map { |c| c["name"] }
|
||||
end
|
||||
|
||||
def test_fit_extension_is_preserved_not_forced_to_gpx
|
||||
path = @store.save(folder: "", filename: "activity.fit", io: StringIO.new("binary"))
|
||||
assert_equal "activity.fit", path
|
||||
end
|
||||
|
||||
def test_unrecognized_extension_gets_gpx_appended
|
||||
path = @store.save(folder: "", filename: "notes.txt", io: StringIO.new("x"))
|
||||
assert_equal "notes.txt.gpx", path
|
||||
end
|
||||
|
||||
def test_colliding_filenames_are_disambiguated
|
||||
@store.save(folder: "", filename: "ride.gpx", io: StringIO.new("a"))
|
||||
path = @store.save(folder: "", filename: "ride.gpx", io: StringIO.new("b"))
|
||||
|
||||
assert_equal "ride-1.gpx", path
|
||||
end
|
||||
|
||||
def test_save_creates_the_target_folder
|
||||
@store.save(folder: "trips/2026", filename: "ride.gpx", io: StringIO.new("x"))
|
||||
|
||||
folder = @store.tree["children"].find { |c| c["name"] == "trips" }["children"].find { |c| c["name"] == "2026" }
|
||||
assert_equal ["ride.gpx"], folder["children"].map { |c| c["name"] }
|
||||
end
|
||||
|
||||
def test_path_traversal_is_rejected
|
||||
assert_raises(Maptool::GpxStore::InvalidPath) { @store.resolve_file("../../etc/passwd") }
|
||||
assert_raises(Maptool::GpxStore::InvalidPath) { @store.save(folder: "../escape", filename: "x.gpx", io: StringIO.new("x")) }
|
||||
end
|
||||
|
||||
def test_delete_file
|
||||
@store.save(folder: "", filename: "ride.gpx", io: StringIO.new("x"))
|
||||
@store.delete_file("ride.gpx")
|
||||
|
||||
assert_empty @store.tree["children"]
|
||||
end
|
||||
|
||||
def test_delete_missing_file_raises_enoent
|
||||
assert_raises(Errno::ENOENT) { @store.delete_file("nope.gpx") }
|
||||
end
|
||||
|
||||
def test_delete_folder_refuses_the_store_root
|
||||
assert_raises(Maptool::GpxStore::InvalidPath) { @store.delete_folder("") }
|
||||
end
|
||||
|
||||
def test_move_relocates_and_disambiguates
|
||||
@store.save(folder: "", filename: "ride.gpx", io: StringIO.new("a"))
|
||||
@store.save(folder: "archive", filename: "ride.gpx", io: StringIO.new("b"))
|
||||
|
||||
new_path = @store.move(from: "ride.gpx", to_folder: "archive")
|
||||
|
||||
assert_equal "archive/ride-1.gpx", new_path
|
||||
assert_empty @store.tree["children"].reject { |c| c["name"] == "archive" }
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user