diff --git a/app/controllers/api/v1/maps/tile_usage_controller.rb b/app/controllers/api/v1/maps/tile_usage_controller.rb new file mode 100644 index 00000000..43f8f070 --- /dev/null +++ b/app/controllers/api/v1/maps/tile_usage_controller.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class Api::V1::Maps::TileUsageController < ApiController + def create + Maps::TileUsage::Track.new(tile_usage_params[:count].to_i).call + + head :ok + end + + private + + def tile_usage_params + params.require(:tile_usage).permit(:count) + end +end diff --git a/app/controllers/api/v1/tile_usages_controller.rb b/app/controllers/api/v1/tile_usages_controller.rb deleted file mode 100644 index d5d74d9d..00000000 --- a/app/controllers/api/v1/tile_usages_controller.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::TileUsagesController < ApiController - def create - TileUsage::Track.new(params[:tile_count].to_i).call - - head :ok - end -end diff --git a/app/javascript/maps/tile_monitor.js b/app/javascript/maps/tile_monitor.js index bd5da516..3a4ff36e 100644 --- a/app/javascript/maps/tile_monitor.js +++ b/app/javascript/maps/tile_monitor.js @@ -40,14 +40,16 @@ export class TileMonitor { const currentCount = this.tileQueue; console.log('Sending tile usage batch:', currentCount); - fetch('/api/v1/tile_usages', { + fetch('/api/v1/maps/tile_usage', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, body: JSON.stringify({ - tile_count: currentCount + tile_usage: { + count: currentCount + } }) }) .then(response => { diff --git a/app/services/tile_usage/track.rb b/app/services/maps/tile_usage/track.rb similarity index 92% rename from app/services/tile_usage/track.rb rename to app/services/maps/tile_usage/track.rb index 69d1b361..13fd1711 100644 --- a/app/services/tile_usage/track.rb +++ b/app/services/maps/tile_usage/track.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class TileUsage::Track +class Maps::TileUsage::Track def initialize(count = 1) @count = count end diff --git a/config/routes.rb b/config/routes.rb index 45b55576..09ca7fbc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -97,7 +97,9 @@ Rails.application.routes.draw do end end - resources :tile_usages, only: [:create] + namespace :maps do + resources :tile_usage, only: [:create] + end end end end diff --git a/spec/requests/api/v1/maps/tile_usage_spec.rb b/spec/requests/api/v1/maps/tile_usage_spec.rb new file mode 100644 index 00000000..8c35d9a6 --- /dev/null +++ b/spec/requests/api/v1/maps/tile_usage_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Api::V1::Maps::TileUsage', type: :request do + describe 'POST /api/v1/maps/tile_usage' do + let(:tile_count) { 5 } + let(:track_service) { instance_double(Maps::TileUsage::Track) } + + before do + allow(Maps::TileUsage::Track).to receive(:new).with(tile_count).and_return(track_service) + allow(track_service).to receive(:call) + end + + context 'when user is authenticated' do + let(:user) { create(:user) } + + it 'tracks tile usage' do + post '/api/v1/maps/tile_usage', + params: { tile_usage: { count: tile_count } }, + headers: { 'Authorization' => "Bearer #{user.api_key}" } + + expect(Maps::TileUsage::Track).to have_received(:new).with(tile_count) + expect(track_service).to have_received(:call) + expect(response).to have_http_status(:ok) + end + end + + context 'when user is not authenticated' do + it 'returns unauthorized' do + post '/api/v1/maps/tile_usage', params: { tile_usage: { count: tile_count } } + + expect(response).to have_http_status(:unauthorized) + end + end + end +end diff --git a/spec/services/maps/tile_usage/track_spec.rb b/spec/services/maps/tile_usage/track_spec.rb new file mode 100644 index 00000000..82f0360c --- /dev/null +++ b/spec/services/maps/tile_usage/track_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'prometheus_exporter/client' + +RSpec.describe Maps::TileUsage::Track do + describe '#call' do + subject(:track) { described_class.new(tile_count).call } + + let(:tile_count) { 5 } + let(:prometheus_client) { instance_double(PrometheusExporter::Client) } + + before do + allow(PrometheusExporter::Client).to receive(:default).and_return(prometheus_client) + end + + it 'tracks tile usage' do + expect(prometheus_client).to receive(:send_json).with( + { + type: 'counter', + name: 'dawarich_map_tiles', + value: tile_count + } + ) + + track + end + end +end