mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
Fix failing specs
This commit is contained in:
parent
2bd0390d1a
commit
584daadb5c
10 changed files with 57 additions and 58 deletions
|
|
@ -8,8 +8,10 @@ class Api::V1::Maps::HexagonsController < ApiController
|
|||
|
||||
result = Maps::HexagonRequestHandler.new(
|
||||
params: params,
|
||||
user: current_api_user,
|
||||
context: context
|
||||
user: context[:user] || current_api_user,
|
||||
stat: context[:stat],
|
||||
start_date: context[:start_date],
|
||||
end_date: context[:end_date]
|
||||
).call
|
||||
|
||||
render json: result
|
||||
|
|
|
|||
|
|
@ -72,7 +72,11 @@ module Maps
|
|||
if param.match?(/^\d+$/)
|
||||
param.to_i
|
||||
else
|
||||
Time.zone.parse(param).to_i
|
||||
parsed_time = Time.zone.parse(param)
|
||||
if parsed_time.nil?
|
||||
raise ArgumentError, "Invalid date format: #{param}"
|
||||
end
|
||||
parsed_time.to_i
|
||||
end
|
||||
when Integer
|
||||
param
|
||||
|
|
|
|||
|
|
@ -58,15 +58,11 @@ module Maps
|
|||
{
|
||||
'type' => 'Feature',
|
||||
'id' => index + 1,
|
||||
'geometry' => generate_hexagon_geometry_from_h3(h3_index),
|
||||
'geometry' => Maps::HexagonPolygonGenerator.new(h3_index:).call,
|
||||
'properties' => build_hexagon_properties(index, count, earliest, latest)
|
||||
}
|
||||
end
|
||||
|
||||
def generate_hexagon_geometry_from_h3(h3_index)
|
||||
Maps::HexagonPolygonGenerator.new(h3_index: h3_index).call
|
||||
end
|
||||
|
||||
def build_hexagon_properties(index, count, earliest, latest)
|
||||
{
|
||||
'hex_id' => index + 1,
|
||||
|
|
|
|||
|
|
@ -2,30 +2,16 @@
|
|||
|
||||
module Maps
|
||||
class HexagonPolygonGenerator
|
||||
def initialize(center_lng: nil, center_lat: nil, h3_resolution: 5, h3_index: nil)
|
||||
@center_lng = center_lng
|
||||
@center_lat = center_lat
|
||||
@h3_resolution = h3_resolution
|
||||
def initialize(h3_index:)
|
||||
@h3_index = h3_index
|
||||
end
|
||||
|
||||
def call
|
||||
generate_h3_hexagon_polygon
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :center_lng, :center_lat, :h3_resolution, :h3_index
|
||||
|
||||
def generate_h3_hexagon_polygon
|
||||
# Convert coordinates to H3 format [lat, lng]
|
||||
coordinates = [center_lat, center_lng]
|
||||
|
||||
# Get H3 index for these coordinates at specified resolution
|
||||
h3_index = H3.from_geo_coordinates(coordinates, h3_resolution)
|
||||
# Parse H3 index from hex string if needed
|
||||
index = h3_index.is_a?(String) ? h3_index.to_i(16) : h3_index
|
||||
|
||||
# Get the boundary coordinates for this H3 hexagon
|
||||
boundary_coordinates = H3.to_boundary(h3_index)
|
||||
boundary_coordinates = H3.to_boundary(index)
|
||||
|
||||
# Convert to GeoJSON polygon format (lng, lat)
|
||||
polygon_coordinates = boundary_coordinates.map { [_2, _1] }
|
||||
|
|
@ -38,5 +24,9 @@ module Maps
|
|||
'coordinates' => [polygon_coordinates]
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :h3_index
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddH3HexIdsToStats < ActiveRecord::Migration[8.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_column :stats, :h3_hex_ids, :jsonb, default: {}
|
||||
add_index :stats, :h3_hex_ids, using: :gin, where: "(h3_hex_ids IS NOT NULL AND h3_hex_ids != '{}'::jsonb)"
|
||||
add_index :stats, :h3_hex_ids, using: :gin,
|
||||
where: "(h3_hex_ids IS NOT NULL AND h3_hex_ids != '{}'::jsonb)",
|
||||
algorithm: :concurrently
|
||||
end
|
||||
end
|
||||
|
|
|
|||
4
db/schema.rb
generated
4
db/schema.rb
generated
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_09_10_224714) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_09_18_215512) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
enable_extension "postgis"
|
||||
|
|
@ -222,7 +222,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_09_10_224714) do
|
|||
t.jsonb "daily_distance", default: {}
|
||||
t.jsonb "sharing_settings", default: {}
|
||||
t.uuid "sharing_uuid"
|
||||
t.jsonb "h3_hex_ids", default: {}
|
||||
t.index ["distance"], name: "index_stats_on_distance"
|
||||
t.index ["h3_hex_ids"], name: "index_stats_on_h3_hex_ids", where: "((h3_hex_ids IS NOT NULL) AND (h3_hex_ids <> '{}'::jsonb))", using: :gin
|
||||
t.index ["month"], name: "index_stats_on_month"
|
||||
t.index ["sharing_uuid"], name: "index_stats_on_sharing_uuid", unique: true
|
||||
t.index ["user_id"], name: "index_stats_on_user_id"
|
||||
|
|
|
|||
|
|
@ -172,14 +172,14 @@ RSpec.describe 'Api::V1::Maps::Hexagons', type: :request do
|
|||
|
||||
context 'with pre-calculated hexagon centers' do
|
||||
let(:pre_calculated_centers) do
|
||||
[
|
||||
[-74.0, 40.7, 1_717_200_000, 1_717_203_600], # lng, lat, earliest, latest timestamps
|
||||
[-74.01, 40.71, 1_717_210_000, 1_717_213_600],
|
||||
[-74.02, 40.72, 1_717_220_000, 1_717_223_600]
|
||||
]
|
||||
{
|
||||
'8a1fb46622dffff' => [5, 1_717_200_000, 1_717_203_600], # count, earliest, latest timestamps
|
||||
'8a1fb46622e7fff' => [3, 1_717_210_000, 1_717_213_600],
|
||||
'8a1fb46632dffff' => [8, 1_717_220_000, 1_717_223_600]
|
||||
}
|
||||
end
|
||||
let(:stat) do
|
||||
create(:stat, :with_sharing_enabled, user:, year: 2024, month: 6, hexagon_centers: pre_calculated_centers)
|
||||
create(:stat, :with_sharing_enabled, user:, year: 2024, month: 6, h3_hex_ids: pre_calculated_centers)
|
||||
end
|
||||
|
||||
it 'uses pre-calculated hexagon centers instead of on-the-fly calculation' do
|
||||
|
|
@ -228,7 +228,7 @@ RSpec.describe 'Api::V1::Maps::Hexagons', type: :request do
|
|||
context 'with legacy area_too_large hexagon data' do
|
||||
let(:stat) do
|
||||
create(:stat, :with_sharing_enabled, user:, year: 2024, month: 6,
|
||||
hexagon_centers: { 'area_too_large' => true })
|
||||
h3_hex_ids: { 'area_too_large' => true })
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
@ -246,7 +246,7 @@ RSpec.describe 'Api::V1::Maps::Hexagons', type: :request do
|
|||
get '/api/v1/maps/hexagons', params: uuid_params
|
||||
|
||||
# The endpoint should handle the legacy data gracefully and not crash
|
||||
# We're primarily testing that the condition `@stat&.hexagon_centers&.dig('area_too_large')` is covered
|
||||
# We're primarily testing that the condition `@stat&.h3_hex_ids&.dig('area_too_large')` is covered
|
||||
expect([200, 400, 500]).to include(response.status)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ RSpec.describe Maps::HexagonCenterManager do
|
|||
|
||||
context 'with pre-calculated hexagon centers' do
|
||||
let(:pre_calculated_centers) do
|
||||
[
|
||||
[-74.0, 40.7, 1_717_200_000, 1_717_203_600], # lng, lat, earliest, latest timestamps
|
||||
[-74.01, 40.71, 1_717_210_000, 1_717_213_600],
|
||||
[-74.02, 40.72, 1_717_220_000, 1_717_223_600]
|
||||
]
|
||||
{
|
||||
'8a1fb46622dffff' => [5, 1_717_200_000, 1_717_203_600], # count, earliest, latest timestamps
|
||||
'8a1fb46622e7fff' => [3, 1_717_210_000, 1_717_213_600],
|
||||
'8a1fb46632dffff' => [8, 1_717_220_000, 1_717_223_600]
|
||||
}
|
||||
end
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, hexagon_centers: pre_calculated_centers) }
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, h3_hex_ids: pre_calculated_centers) }
|
||||
|
||||
it 'returns success with pre-calculated data' do
|
||||
result = manage_centers
|
||||
|
|
@ -51,7 +51,7 @@ RSpec.describe Maps::HexagonCenterManager do
|
|||
|
||||
context 'with legacy area_too_large flag' do
|
||||
let(:stat) do
|
||||
create(:stat, user:, year: 2024, month: 6, hexagon_centers: { 'area_too_large' => true })
|
||||
create(:stat, user:, year: 2024, month: 6, h3_hex_ids: { 'area_too_large' => true })
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
@ -69,7 +69,7 @@ RSpec.describe Maps::HexagonCenterManager do
|
|||
end
|
||||
|
||||
it 'recalculates and updates the stat' do
|
||||
expect(stat).to receive(:update).with(hexagon_centers: new_centers)
|
||||
expect(stat).to receive(:update).with(h3_hex_ids: new_centers)
|
||||
|
||||
result = manage_centers
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ RSpec.describe Maps::HexagonCenterManager do
|
|||
end
|
||||
|
||||
context 'with stat but no hexagon_centers' do
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, hexagon_centers: nil) }
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, h3_hex_ids: nil) }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(manage_centers).to be_nil
|
||||
|
|
@ -113,7 +113,7 @@ RSpec.describe Maps::HexagonCenterManager do
|
|||
end
|
||||
|
||||
context 'with empty hexagon_centers' do
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, hexagon_centers: []) }
|
||||
let(:stat) { create(:stat, user:, year: 2024, month: 6, h3_hex_ids: []) }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(manage_centers).to be_nil
|
||||
|
|
|
|||
|
|
@ -43,14 +43,14 @@ RSpec.describe Maps::HexagonRequestHandler do
|
|||
|
||||
context 'with public sharing UUID and pre-calculated centers' do
|
||||
let(:pre_calculated_centers) do
|
||||
[
|
||||
[-74.0, 40.7, 1_717_200_000, 1_717_203_600],
|
||||
[-74.01, 40.71, 1_717_210_000, 1_717_213_600]
|
||||
]
|
||||
{
|
||||
'8a1fb46622dffff' => [5, 1_717_200_000, 1_717_203_600],
|
||||
'8a1fb46622e7fff' => [3, 1_717_210_000, 1_717_213_600]
|
||||
}
|
||||
end
|
||||
let(:stat) do
|
||||
create(:stat, :with_sharing_enabled, user:, year: 2024, month: 6,
|
||||
hexagon_centers: pre_calculated_centers)
|
||||
h3_hex_ids: pre_calculated_centers)
|
||||
end
|
||||
let(:params) do
|
||||
ActionController::Parameters.new(
|
||||
|
|
@ -101,7 +101,7 @@ RSpec.describe Maps::HexagonRequestHandler do
|
|||
context 'with legacy area_too_large that can be recalculated' do
|
||||
let(:stat) do
|
||||
create(:stat, :with_sharing_enabled, user:, year: 2024, month: 6,
|
||||
hexagon_centers: { 'area_too_large' => true })
|
||||
h3_hex_ids: { 'area_too_large' => true })
|
||||
end
|
||||
let(:params) do
|
||||
ActionController::Parameters.new(
|
||||
|
|
@ -129,7 +129,7 @@ RSpec.describe Maps::HexagonRequestHandler do
|
|||
expect(result['metadata']['pre_calculated']).to be true
|
||||
|
||||
# Verify that the stat was updated with new centers (reload to check persistence)
|
||||
expect(stat.reload.hexagon_centers).to eq([[-74.0, 40.7, 1_717_200_000, 1_717_203_600]])
|
||||
expect(stat.reload.h3_hex_ids).to eq([[-74.0, 40.7, 1_717_200_000, 1_717_203_600]])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -162,14 +162,15 @@ RSpec.describe Stats::CalculateMonth do
|
|||
expect(total_points).to eq(2)
|
||||
end
|
||||
|
||||
|
||||
context 'when H3 raises an error' do
|
||||
before do
|
||||
allow(H3).to receive(:from_geo_coordinates).and_raise(StandardError, 'H3 error')
|
||||
end
|
||||
|
||||
it 'raises PostGISError' do
|
||||
expect { calculate_hexagons }.to raise_error(Stats::CalculateMonth::PostGISError, /Failed to calculate H3 hexagon centers/)
|
||||
expect do
|
||||
calculate_hexagons
|
||||
end.to raise_error(Stats::CalculateMonth::PostGISError, /Failed to calculate H3 hexagon centers/)
|
||||
end
|
||||
|
||||
it 'reports the exception' do
|
||||
|
|
@ -185,7 +186,7 @@ RSpec.describe Stats::CalculateMonth do
|
|||
|
||||
it 'handles string timestamps' do
|
||||
result = service.send(:parse_date_parameter, '1640995200')
|
||||
expect(result).to eq(1640995200)
|
||||
expect(result).to eq(1_640_995_200)
|
||||
end
|
||||
|
||||
it 'handles ISO date strings' do
|
||||
|
|
@ -194,8 +195,8 @@ RSpec.describe Stats::CalculateMonth do
|
|||
end
|
||||
|
||||
it 'handles integer timestamps' do
|
||||
result = service.send(:parse_date_parameter, 1640995200)
|
||||
expect(result).to eq(1640995200)
|
||||
result = service.send(:parse_date_parameter, 1_640_995_200)
|
||||
expect(result).to eq(1_640_995_200)
|
||||
end
|
||||
|
||||
it 'handles edge case gracefully' do
|
||||
|
|
|
|||
Loading…
Reference in a new issue