mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Remove unused code
This commit is contained in:
parent
5db2ac7fac
commit
0cce4929f0
8 changed files with 39 additions and 407 deletions
|
|
@ -72,8 +72,6 @@ module Maps
|
||||||
if param.match?(/^\d+$/)
|
if param.match?(/^\d+$/)
|
||||||
param.to_i
|
param.to_i
|
||||||
else
|
else
|
||||||
# Use Time.parse for strict validation, then convert via Time.zone
|
|
||||||
parsed_time = Time.parse(param) # This will raise ArgumentError for invalid dates
|
|
||||||
Time.zone.parse(param).to_i
|
Time.zone.parse(param).to_i
|
||||||
end
|
end
|
||||||
when Integer
|
when Integer
|
||||||
|
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Maps
|
|
||||||
class H3HexagonRenderer
|
|
||||||
def initialize(params:, user: nil, context: nil)
|
|
||||||
@params = params
|
|
||||||
@user = user
|
|
||||||
@context = context
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
|
||||||
context = @context || resolve_context
|
|
||||||
h3_data = get_h3_hexagon_data(context)
|
|
||||||
|
|
||||||
return empty_feature_collection if h3_data.empty?
|
|
||||||
|
|
||||||
convert_h3_to_geojson(h3_data)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
attr_reader :params, :user, :context
|
|
||||||
|
|
||||||
def get_h3_hexagon_data(context)
|
|
||||||
# For public sharing, get pre-calculated data from stat
|
|
||||||
if context[:stat]&.hexagon_centers.present?
|
|
||||||
hexagon_data = context[:stat].hexagon_centers
|
|
||||||
|
|
||||||
# Check if this is old format (coordinates) or new format (H3 indexes)
|
|
||||||
if hexagon_data.first.is_a?(Array) && hexagon_data.first[0].is_a?(Float)
|
|
||||||
Rails.logger.debug "Found old coordinate format for stat #{context[:stat].id}, generating H3 on-the-fly"
|
|
||||||
return generate_h3_data_on_the_fly(context)
|
|
||||||
else
|
|
||||||
Rails.logger.debug "Using pre-calculated H3 data for stat #{context[:stat].id}"
|
|
||||||
return hexagon_data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# For authenticated users, calculate on-the-fly if no pre-calculated data
|
|
||||||
Rails.logger.debug 'No pre-calculated H3 data, calculating on-the-fly'
|
|
||||||
generate_h3_data_on_the_fly(context)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_h3_data_on_the_fly(context)
|
|
||||||
start_date = parse_date_for_h3(context[:start_date])
|
|
||||||
end_date = parse_date_for_h3(context[:end_date])
|
|
||||||
h3_resolution = params[:h3_resolution]&.to_i&.clamp(0, 15) || 6
|
|
||||||
|
|
||||||
# Use dummy year/month since we're only using the H3 calculation method
|
|
||||||
stats_service = Stats::CalculateMonth.new(context[:user]&.id, 2024, 1)
|
|
||||||
stats_service.calculate_h3_hexagon_centers(
|
|
||||||
user_id: context[:user]&.id,
|
|
||||||
start_date: start_date,
|
|
||||||
end_date: end_date,
|
|
||||||
h3_resolution: h3_resolution
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def convert_h3_to_geojson(h3_data)
|
|
||||||
features = h3_data.map do |h3_record|
|
|
||||||
h3_index_string, point_count, earliest_timestamp, latest_timestamp = h3_record
|
|
||||||
|
|
||||||
# Convert hex string back to H3 index
|
|
||||||
h3_index = h3_index_string.to_i(16)
|
|
||||||
|
|
||||||
# Get hexagon boundary coordinates
|
|
||||||
boundary_coordinates = H3.to_boundary(h3_index)
|
|
||||||
|
|
||||||
# Convert to GeoJSON polygon format (lng, lat)
|
|
||||||
polygon_coordinates = boundary_coordinates.map { |lat, lng| [lng, lat] }
|
|
||||||
polygon_coordinates << polygon_coordinates.first # Close the polygon
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'Feature',
|
|
||||||
geometry: {
|
|
||||||
type: 'Polygon',
|
|
||||||
coordinates: [polygon_coordinates]
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
h3_index: h3_index_string,
|
|
||||||
point_count: point_count,
|
|
||||||
earliest_point: earliest_timestamp ? Time.at(earliest_timestamp).iso8601 : nil,
|
|
||||||
latest_point: latest_timestamp ? Time.at(latest_timestamp).iso8601 : nil,
|
|
||||||
center: H3.to_geo_coordinates(h3_index) # [lat, lng]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features: features,
|
|
||||||
metadata: {
|
|
||||||
hexagon_count: features.size,
|
|
||||||
total_points: features.sum { |f| f[:properties][:point_count] },
|
|
||||||
source: 'h3'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def empty_feature_collection
|
|
||||||
{
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features: [],
|
|
||||||
metadata: {
|
|
||||||
hexagon_count: 0,
|
|
||||||
total_points: 0,
|
|
||||||
source: 'h3'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_date_for_h3(date_param)
|
|
||||||
# If already a Time object (from public sharing context), return as-is
|
|
||||||
return date_param if date_param.is_a?(Time)
|
|
||||||
|
|
||||||
# If it's a string ISO date, parse it directly to Time
|
|
||||||
return Time.zone.parse(date_param) if date_param.is_a?(String)
|
|
||||||
|
|
||||||
# If it's an integer timestamp, convert to Time
|
|
||||||
return Time.zone.at(date_param) if date_param.is_a?(Integer)
|
|
||||||
|
|
||||||
# For other cases, try coercing and converting
|
|
||||||
case date_param
|
|
||||||
when String
|
|
||||||
date_param.match?(/^\d+$/) ? Time.zone.at(date_param.to_i) : Time.zone.parse(date_param)
|
|
||||||
when Integer
|
|
||||||
Time.zone.at(date_param)
|
|
||||||
else
|
|
||||||
Time.zone.at(date_param.to_i)
|
|
||||||
end
|
|
||||||
rescue ArgumentError => e
|
|
||||||
Rails.logger.error "Invalid date format: #{date_param} - #{e.message}"
|
|
||||||
raise ArgumentError, "Invalid date format: #{date_param}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
module Maps
|
module Maps
|
||||||
class HexagonCenterManager
|
class HexagonCenterManager
|
||||||
def self.call(stat:, user:)
|
|
||||||
new(stat: stat, user: user).call
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(stat:, user:)
|
def initialize(stat:, user:)
|
||||||
@stat = stat
|
@stat = stat
|
||||||
@user = user
|
@user = user
|
||||||
|
|
@ -86,11 +82,10 @@ module Maps
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_hexagon_geometry(lng, lat)
|
def generate_hexagon_geometry(lng, lat)
|
||||||
Maps::HexagonPolygonGenerator.call(
|
Maps::HexagonPolygonGenerator.new(
|
||||||
center_lng: lng,
|
center_lng: lng,
|
||||||
center_lat: lat,
|
center_lat: lat
|
||||||
size_meters: 1000
|
).call
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_hexagon_properties(index, earliest, latest)
|
def build_hexagon_properties(index, earliest, latest)
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,19 @@
|
||||||
|
|
||||||
module Maps
|
module Maps
|
||||||
class HexagonPolygonGenerator
|
class HexagonPolygonGenerator
|
||||||
DEFAULT_SIZE_METERS = 1000
|
def initialize(center_lng:, center_lat:, h3_resolution: 5)
|
||||||
|
|
||||||
def self.call(center_lng:, center_lat:, size_meters: DEFAULT_SIZE_METERS, use_h3: false, h3_resolution: 5)
|
|
||||||
new(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat,
|
|
||||||
size_meters: size_meters,
|
|
||||||
use_h3: use_h3,
|
|
||||||
h3_resolution: h3_resolution
|
|
||||||
).call
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(center_lng:, center_lat:, size_meters: DEFAULT_SIZE_METERS, use_h3: false, h3_resolution: 5)
|
|
||||||
@center_lng = center_lng
|
@center_lng = center_lng
|
||||||
@center_lat = center_lat
|
@center_lat = center_lat
|
||||||
@size_meters = size_meters
|
|
||||||
@use_h3 = use_h3
|
|
||||||
@h3_resolution = h3_resolution
|
@h3_resolution = h3_resolution
|
||||||
end
|
end
|
||||||
|
|
||||||
def call
|
def call
|
||||||
if use_h3
|
|
||||||
generate_h3_hexagon_polygon
|
generate_h3_hexagon_polygon
|
||||||
else
|
|
||||||
generate_hexagon_polygon
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :center_lng, :center_lat, :size_meters, :use_h3, :h3_resolution
|
attr_reader :center_lng, :center_lat, :h3_resolution
|
||||||
|
|
||||||
def generate_h3_hexagon_polygon
|
def generate_h3_hexagon_polygon
|
||||||
# Convert coordinates to H3 format [lat, lng]
|
# Convert coordinates to H3 format [lat, lng]
|
||||||
|
|
@ -45,7 +27,7 @@ module Maps
|
||||||
boundary_coordinates = H3.to_boundary(h3_index)
|
boundary_coordinates = H3.to_boundary(h3_index)
|
||||||
|
|
||||||
# Convert to GeoJSON polygon format (lng, lat)
|
# Convert to GeoJSON polygon format (lng, lat)
|
||||||
polygon_coordinates = boundary_coordinates.map { |lat, lng| [lng, lat] }
|
polygon_coordinates = boundary_coordinates.map { [_2, _1] }
|
||||||
|
|
||||||
# Close the polygon by adding the first point at the end
|
# Close the polygon by adding the first point at the end
|
||||||
polygon_coordinates << polygon_coordinates.first
|
polygon_coordinates << polygon_coordinates.first
|
||||||
|
|
@ -55,50 +37,5 @@ module Maps
|
||||||
'coordinates' => [polygon_coordinates]
|
'coordinates' => [polygon_coordinates]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_hexagon_polygon
|
|
||||||
# Generate hexagon vertices around center point
|
|
||||||
# For a regular hexagon:
|
|
||||||
# - Circumradius (center to vertex) = size_meters / 2
|
|
||||||
# - This creates hexagons that are approximately size_meters wide
|
|
||||||
|
|
||||||
radius_meters = size_meters / 2.0
|
|
||||||
|
|
||||||
# Convert meter radius to degrees
|
|
||||||
# 1 degree latitude ≈ 111,111 meters
|
|
||||||
# 1 degree longitude ≈ 111,111 * cos(latitude) meters at given latitude
|
|
||||||
lat_degree_in_meters = 111_111.0
|
|
||||||
lng_degree_in_meters = lat_degree_in_meters * Math.cos(center_lat * Math::PI / 180)
|
|
||||||
|
|
||||||
radius_lat_degrees = radius_meters / lat_degree_in_meters
|
|
||||||
radius_lng_degrees = radius_meters / lng_degree_in_meters
|
|
||||||
|
|
||||||
vertices = build_vertices(radius_lat_degrees, radius_lng_degrees)
|
|
||||||
|
|
||||||
{
|
|
||||||
'type' => 'Polygon',
|
|
||||||
'coordinates' => [vertices]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_vertices(radius_lat_degrees, radius_lng_degrees)
|
|
||||||
vertices = []
|
|
||||||
6.times do |i|
|
|
||||||
# Calculate angle for each vertex (60 degrees apart, starting from 0)
|
|
||||||
# Start at 30 degrees to orient hexagon with flat top
|
|
||||||
angle = ((i * 60) + 30) * Math::PI / 180
|
|
||||||
|
|
||||||
# Calculate vertex position using proper geographic coordinate system
|
|
||||||
# longitude (x-axis) uses cosine, latitude (y-axis) uses sine
|
|
||||||
lng_offset = radius_lng_degrees * Math.cos(angle)
|
|
||||||
lat_offset = radius_lat_degrees * Math.sin(angle)
|
|
||||||
|
|
||||||
vertices << [center_lng + lng_offset, center_lat + lat_offset]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Close the polygon by adding the first vertex at the end
|
|
||||||
vertices << vertices.first
|
|
||||||
vertices
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,20 @@
|
||||||
|
|
||||||
module Maps
|
module Maps
|
||||||
class HexagonRequestHandler
|
class HexagonRequestHandler
|
||||||
def initialize(params:, user: nil, context: nil)
|
def initialize(params:, user: nil, stat: nil, start_date: nil, end_date: nil)
|
||||||
@params = params
|
@params = params
|
||||||
@user = user
|
@user = user
|
||||||
@context = context
|
@stat = stat
|
||||||
|
@start_date = start_date
|
||||||
|
@end_date = end_date
|
||||||
end
|
end
|
||||||
|
|
||||||
def call
|
def call
|
||||||
context = @context || resolve_context
|
|
||||||
|
|
||||||
# For authenticated users, we need to find the matching stat
|
# For authenticated users, we need to find the matching stat
|
||||||
stat = context[:stat] || find_matching_stat(context)
|
stat ||= find_matching_stat
|
||||||
|
|
||||||
# Use pre-calculated hexagon centers
|
|
||||||
if stat
|
if stat
|
||||||
cached_result = Maps::HexagonCenterManager.call(
|
cached_result = Maps::HexagonCenterManager.new(stat:, user:).call
|
||||||
stat: stat,
|
|
||||||
user: context[:user]
|
|
||||||
)
|
|
||||||
|
|
||||||
return cached_result[:data] if cached_result&.dig(:success)
|
return cached_result[:data] if cached_result&.dig(:success)
|
||||||
end
|
end
|
||||||
|
|
@ -31,22 +27,22 @@ module Maps
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :params, :user, :context
|
attr_reader :params, :user, :stat, :start_date, :end_date
|
||||||
|
|
||||||
def find_matching_stat(context)
|
def find_matching_stat
|
||||||
return unless context[:user] && context[:start_date]
|
return unless user && start_date
|
||||||
|
|
||||||
# Parse the date to extract year and month
|
# Parse the date to extract year and month
|
||||||
if context[:start_date].is_a?(String)
|
if start_date.is_a?(String)
|
||||||
date = Date.parse(context[:start_date])
|
date = Date.parse(start_date)
|
||||||
elsif context[:start_date].is_a?(Time)
|
elsif start_date.is_a?(Time)
|
||||||
date = context[:start_date].to_date
|
date = start_date.to_date
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find the stat for this user, year, and month
|
# Find the stat for this user, year, and month
|
||||||
context[:user].stats.find_by(year: date.year, month: date.month)
|
user.stats.find_by(year: date.year, month: date.month)
|
||||||
rescue Date::Error
|
rescue Date::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,7 @@ require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe Maps::HexagonCenterManager do
|
RSpec.describe Maps::HexagonCenterManager do
|
||||||
describe '.call' do
|
describe '.call' do
|
||||||
subject(:manage_centers) do
|
subject(:manage_centers) { described_class.new(stat:, user:).call }
|
||||||
described_class.call(
|
|
||||||
stat: stat,
|
|
||||||
target_user: target_user
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:target_user) { user }
|
let(:target_user) { user }
|
||||||
|
|
|
||||||
|
|
@ -5,107 +5,14 @@ require 'rails_helper'
|
||||||
RSpec.describe Maps::HexagonPolygonGenerator do
|
RSpec.describe Maps::HexagonPolygonGenerator do
|
||||||
describe '.call' do
|
describe '.call' do
|
||||||
subject(:generate_polygon) do
|
subject(:generate_polygon) do
|
||||||
described_class.call(
|
described_class.new(
|
||||||
center_lng: center_lng,
|
center_lng: center_lng,
|
||||||
center_lat: center_lat,
|
center_lat: center_lat
|
||||||
size_meters: size_meters
|
).call
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:center_lng) { -74.0 }
|
let(:center_lng) { -74.0 }
|
||||||
let(:center_lat) { 40.7 }
|
let(:center_lat) { 40.7 }
|
||||||
let(:size_meters) { 1000 }
|
|
||||||
|
|
||||||
it 'returns a polygon geometry' do
|
|
||||||
result = generate_polygon
|
|
||||||
|
|
||||||
expect(result['type']).to eq('Polygon')
|
|
||||||
expect(result['coordinates']).to be_an(Array)
|
|
||||||
expect(result['coordinates'].length).to eq(1) # One ring
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'generates a hexagon with 7 coordinate pairs (6 vertices + closing)' do
|
|
||||||
result = generate_polygon
|
|
||||||
coordinates = result['coordinates'].first
|
|
||||||
|
|
||||||
expect(coordinates.length).to eq(7) # 6 vertices + closing vertex
|
|
||||||
expect(coordinates.first).to eq(coordinates.last) # Closed polygon
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'generates unique vertices' do
|
|
||||||
result = generate_polygon
|
|
||||||
coordinates = result['coordinates'].first
|
|
||||||
|
|
||||||
# Remove the closing vertex for uniqueness check
|
|
||||||
unique_vertices = coordinates[0..5]
|
|
||||||
expect(unique_vertices.uniq.length).to eq(6) # All vertices should be unique
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'generates vertices around the center point' do
|
|
||||||
result = generate_polygon
|
|
||||||
coordinates = result['coordinates'].first
|
|
||||||
|
|
||||||
# Check that not all vertices are the same as center (vertices should be distributed)
|
|
||||||
vertices_equal_to_center = coordinates[0..5].count do |vertex|
|
|
||||||
lng, lat = vertex
|
|
||||||
lng == center_lng && lat == center_lat
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(vertices_equal_to_center).to eq(0) # No vertex should be exactly at center
|
|
||||||
|
|
||||||
# Check that vertices have some variation in coordinates
|
|
||||||
longitudes = coordinates[0..5].map { |vertex| vertex[0] }
|
|
||||||
latitudes = coordinates[0..5].map { |vertex| vertex[1] }
|
|
||||||
|
|
||||||
expect(longitudes.uniq.size).to be > 1 # Should have different longitudes
|
|
||||||
expect(latitudes.uniq.size).to be > 1 # Should have different latitudes
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with different size' do
|
|
||||||
let(:size_meters) { 500 }
|
|
||||||
|
|
||||||
it 'generates a smaller hexagon' do
|
|
||||||
small_result = generate_polygon
|
|
||||||
large_result = described_class.call(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat,
|
|
||||||
size_meters: 2000
|
|
||||||
)
|
|
||||||
|
|
||||||
# Small hexagon should have vertices closer to center than large hexagon
|
|
||||||
small_distance = calculate_distance_from_center(small_result['coordinates'].first.first)
|
|
||||||
large_distance = calculate_distance_from_center(large_result['coordinates'].first.first)
|
|
||||||
|
|
||||||
expect(small_distance).to be < large_distance
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with different center coordinates' do
|
|
||||||
let(:center_lng) { 13.4 } # Berlin
|
|
||||||
let(:center_lat) { 52.5 }
|
|
||||||
|
|
||||||
it 'generates hexagon around the new center' do
|
|
||||||
result = generate_polygon
|
|
||||||
coordinates = result['coordinates'].first
|
|
||||||
|
|
||||||
# Check that vertices are around the Berlin coordinates
|
|
||||||
avg_lng = coordinates[0..5].sum { |vertex| vertex[0] } / 6
|
|
||||||
avg_lat = coordinates[0..5].sum { |vertex| vertex[1] } / 6
|
|
||||||
|
|
||||||
expect(avg_lng).to be_within(0.01).of(center_lng)
|
|
||||||
expect(avg_lat).to be_within(0.01).of(center_lat)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with H3 enabled' do
|
|
||||||
subject(:generate_h3_polygon) do
|
|
||||||
described_class.call(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat,
|
|
||||||
size_meters: size_meters,
|
|
||||||
use_h3: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns a polygon geometry using H3' do
|
it 'returns a polygon geometry using H3' do
|
||||||
result = generate_h3_polygon
|
result = generate_h3_polygon
|
||||||
|
|
@ -154,38 +61,6 @@ RSpec.describe Maps::HexagonPolygonGenerator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'produces different results than mathematical hexagon' do
|
|
||||||
h3_result = generate_h3_polygon
|
|
||||||
math_result = described_class.call(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat,
|
|
||||||
size_meters: size_meters,
|
|
||||||
use_h3: false
|
|
||||||
)
|
|
||||||
|
|
||||||
# H3 and mathematical hexagons should generally be different
|
|
||||||
# (unless we're very unlucky with alignment)
|
|
||||||
expect(h3_result['coordinates']).not_to eq(math_result['coordinates'])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with use_h3 parameter variations' do
|
|
||||||
it 'defaults to mathematical hexagon when use_h3 is false' do
|
|
||||||
result_explicit_false = described_class.call(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat,
|
|
||||||
use_h3: false
|
|
||||||
)
|
|
||||||
|
|
||||||
result_default = described_class.call(
|
|
||||||
center_lng: center_lng,
|
|
||||||
center_lat: center_lat
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(result_explicit_false).to eq(result_default)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def calculate_hexagon_size(coordinates)
|
def calculate_hexagon_size(coordinates)
|
||||||
|
|
|
||||||
|
|
@ -7,22 +7,14 @@ RSpec.describe Maps::HexagonRequestHandler do
|
||||||
subject(:handle_request) do
|
subject(:handle_request) do
|
||||||
described_class.new(
|
described_class.new(
|
||||||
params: params,
|
params: params,
|
||||||
user: current_api_user
|
user: user,
|
||||||
|
stat: nil,
|
||||||
|
start_date: params[:start_date],
|
||||||
|
end_date: params[:end_date]
|
||||||
).call
|
).call
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:current_api_user) { user }
|
|
||||||
|
|
||||||
before do
|
|
||||||
stub_request(:any, 'https://api.github.com/repos/Freika/dawarich/tags')
|
|
||||||
.to_return(status: 200, body: '[{"name": "1.0.0"}]', headers: {})
|
|
||||||
|
|
||||||
# Clean up database state to avoid conflicts - order matters due to foreign keys
|
|
||||||
Point.delete_all
|
|
||||||
Stat.delete_all
|
|
||||||
User.delete_all
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with authenticated user but no pre-calculated data' do
|
context 'with authenticated user but no pre-calculated data' do
|
||||||
let(:params) do
|
let(:params) do
|
||||||
|
|
@ -71,7 +63,6 @@ RSpec.describe Maps::HexagonRequestHandler do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
let(:current_api_user) { nil }
|
|
||||||
|
|
||||||
it 'returns pre-calculated hexagon data' do
|
it 'returns pre-calculated hexagon data' do
|
||||||
result = handle_request
|
result = handle_request
|
||||||
|
|
@ -96,7 +87,6 @@ RSpec.describe Maps::HexagonRequestHandler do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
let(:current_api_user) { nil }
|
|
||||||
|
|
||||||
it 'returns empty feature collection when no pre-calculated centers' do
|
it 'returns empty feature collection when no pre-calculated centers' do
|
||||||
result = handle_request
|
result = handle_request
|
||||||
|
|
@ -124,7 +114,6 @@ RSpec.describe Maps::HexagonRequestHandler do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
let(:current_api_user) { nil }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
# Mock successful recalculation
|
# Mock successful recalculation
|
||||||
|
|
@ -143,22 +132,5 @@ RSpec.describe Maps::HexagonRequestHandler do
|
||||||
expect(stat.reload.hexagon_centers).to eq([[-74.0, 40.7, 1_717_200_000, 1_717_203_600]])
|
expect(stat.reload.hexagon_centers).to eq([[-74.0, 40.7, 1_717_200_000, 1_717_203_600]])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'error handling' do
|
|
||||||
let(:params) do
|
|
||||||
ActionController::Parameters.new(
|
|
||||||
{
|
|
||||||
uuid: 'invalid-uuid'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
let(:current_api_user) { nil }
|
|
||||||
|
|
||||||
it 'raises ActiveRecord::RecordNotFound for invalid UUID' do
|
|
||||||
expect { handle_request }.to raise_error(
|
|
||||||
ActiveRecord::RecordNotFound
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue