Inline Task.for_user into User, add test_helper for env isolation
Task.for_user was only called from User#active_tasks. The
many_through_many association already joins through series, so
the dataset method was redundant indirection.
Tests broke when AUTH_HEADER was set in the shell because CONFIG
loads at require time. A shared test_helper now pins DATABASE_URL
and AUTH_HEADER before any config is read.
Assisted-by: Claude Opus 4.6 via pi
diff --git a/lib/ketchup/config.rb b/lib/ketchup/config.rb
index 53c1ff1..07f29dd 100644
--- a/lib/ketchup/config.rb
+++ b/lib/ketchup/config.rb
@@ -4,15 +4,15 @@
require "securerandom"
Config = Data.define(
- :database_url, #: String
+ :database_url, #: String
:session_secret, #: String
- :auth_header, #: String
- :sentry, #: SentryConfig?
- :otel, #: OtelConfig?
- :default_user, #: String?
- :commit_sha, #: String?
- :change_id, #: String?
- :build_date, #: String?
+ :auth_header, #: String
+ :sentry, #: SentryConfig?
+ :otel, #: OtelConfig?
+ :default_user, #: String?
+ :commit_sha, #: String?
+ :change_id, #: String?
+ :build_date, #: String?
)
class Config
diff --git a/lib/ketchup/models.rb b/lib/ketchup/models.rb
index 024c5ef..f731e69 100644
--- a/lib/ketchup/models.rb
+++ b/lib/ketchup/models.rb
@@ -11,7 +11,14 @@ class User < Sequel::Model
many_through_many :tasks, [[:series, :user_id, :id]], right_primary_key: :series_id
def active_tasks
- Task.active.for_user(self)
+ tasks_dataset
+ .where(completed_at: nil)
+ .select_all(:tasks)
+ .select_append(
+ Sequel[:series][:note],
+ Sequel[:series][:interval_unit],
+ Sequel[:series][:interval_count]
+ )
end
def overdue_tasks
@@ -101,22 +108,4 @@ class Task < Sequel::Model
Task.create(series_id: series.id, due_date: next_date)
end
end
-
- dataset_module do
- def active
- where(completed_at: nil)
- end
-
- def for_user(user)
- join(:series, id: :series_id)
- .where(Sequel[:series][:user_id] => user.id)
- .select_all(:tasks)
- .select_append(
- Sequel[:series][:note],
- Sequel[:series][:interval_unit],
- Sequel[:series][:interval_count]
- )
- end
-
- end
end
diff --git a/lib/ketchup/web.rb b/lib/ketchup/web.rb
index df4c887..00bf1da 100644
--- a/lib/ketchup/web.rb
+++ b/lib/ketchup/web.rb
@@ -14,10 +14,13 @@ class Web < Roda
plugin :sessions, secret: CONFIG.session_secret
plugin :route_csrf, csrf_failure: :empty_403, check_request_methods: %w[POST]
plugin :error_handler do |e|
- raise e unless e.is_a?(Sequel::NoMatchingRow)
-
- response.status = 404
- ""
+ case e
+ when Sequel::NoMatchingRow
+ response.status = 404
+ ""
+ else
+ raise
+ end
end
def current_user
diff --git a/test/test_db.rb b/test/test_db.rb
index c4aa056..778456a 100644
--- a/test/test_db.rb
+++ b/test/test_db.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-ENV["DATABASE_URL"] = ":memory:"
+require_relative "test_helper"
require "minitest/autorun"
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..cf3e458
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+ENV["DATABASE_URL"] = ":memory:"
+ENV["AUTH_HEADER"] = "Remote-User"
diff --git a/test/test_seed.rb b/test/test_seed.rb
index 1435300..c660579 100644
--- a/test/test_seed.rb
+++ b/test/test_seed.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-ENV["DATABASE_URL"] = ":memory:"
+require_relative "test_helper"
require "minitest/autorun"
require_relative "../lib/ketchup/models"
diff --git a/test/test_sole.rb b/test/test_sole.rb
index c5bdc7b..82f415c 100644
--- a/test/test_sole.rb
+++ b/test/test_sole.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-ENV["DATABASE_URL"] = ":memory:"
+require_relative "test_helper"
require "minitest/autorun"
diff --git a/test/test_web.rb b/test/test_web.rb
index 67f4aed..5563b4f 100644
--- a/test/test_web.rb
+++ b/test/test_web.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-ENV["DATABASE_URL"] = ":memory:"
+require_relative "test_helper"
require "minitest/autorun"
require "rack/test"