Replace the toggle-view approach and hidden DOM data carrier with a proper dedicated Charts page: - Move Charts out of Measurements view toggles into its own nav tab and route (GET /charts) - ChartsController serializes readout data as JSON (ordered by taken_at); the view embeds it in a <script type="application/json"> element instead of rendering a hidden copy of the measurements partial just to ferry data attributes to JS - buildCharts() reads from the JSON element directly — no DOM parsing, no sorting in JS (server already orders the data) - Turbo load handler detects the charts page via #charts-data presence - Add controller tests (authentication, data shape, ordering, data isolation between users) and system tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.2 KiB
Ruby
64 lines
2.2 KiB
Ruby
require "test_helper"
|
|
|
|
class ChartsControllerTest < ActionDispatch::IntegrationTest
|
|
setup do
|
|
host! '127.0.0.1'
|
|
@user = users(:alice)
|
|
post new_user_session_path, params: { user: { email: @user.email, password: 'alice' } }
|
|
@quantity = @user.quantities.create!(name: 'Weight')
|
|
@unit = @user.units.create!(symbol: 'kg')
|
|
end
|
|
|
|
test "requires authentication" do
|
|
delete destroy_user_session_path
|
|
get charts_path
|
|
assert_response :redirect
|
|
end
|
|
|
|
test "index returns ok" do
|
|
get charts_path
|
|
assert_response :success
|
|
end
|
|
|
|
test "embeds readout data as JSON in script tag" do
|
|
users(:alice).readouts.create!(quantity: @quantity, unit: @unit, value: 82.5, taken_at: 1.day.ago)
|
|
|
|
get charts_path
|
|
|
|
assert_select 'script#charts-data[type="application/json"]' do |elements|
|
|
data = JSON.parse(elements.first.children.first.to_s)
|
|
assert_equal 1, data.size
|
|
assert_equal 'Weight', data.first['quantityName']
|
|
assert_in_delta 82.5, data.first['value']
|
|
assert_equal 'kg', data.first['unit']
|
|
assert_not_nil data.first['takenAt']
|
|
end
|
|
end
|
|
|
|
test "orders readouts by taken_at ascending" do
|
|
older = users(:alice).readouts.create!(quantity: @quantity, unit: @unit, value: 80.0, taken_at: 2.days.ago)
|
|
newer = users(:alice).readouts.create!(quantity: @quantity, unit: @unit, value: 82.5, taken_at: 1.day.ago)
|
|
|
|
get charts_path
|
|
|
|
assert_select 'script#charts-data[type="application/json"]' do |elements|
|
|
data = JSON.parse(elements.first.children.first.to_s)
|
|
assert_equal older.taken_at.iso8601, data.first['takenAt']
|
|
assert_equal newer.taken_at.iso8601, data.last['takenAt']
|
|
end
|
|
end
|
|
|
|
test "does not expose other users readouts" do
|
|
bob_quantity = users(:bob).quantities.create!(name: 'Steps')
|
|
bob_unit = users(:bob).units.create!(symbol: 'steps')
|
|
users(:bob).readouts.create!(quantity: bob_quantity, unit: bob_unit, value: 5000, taken_at: 1.day.ago)
|
|
|
|
get charts_path
|
|
|
|
assert_select 'script#charts-data[type="application/json"]' do |elements|
|
|
data = JSON.parse(elements.first.children.first.to_s)
|
|
assert data.none? { |r| r['quantityName'] == 'Steps' }, "Bob's data must not appear"
|
|
end
|
|
end
|
|
end
|