# frozen_string_literal: true require 'rails_helper' RSpec.describe 'Api::V1::Points', type: :request do let!(:user) { create(:user) } let!(:points) do (1..15).map do |i| create(:point, user:, timestamp: 1.day.ago + i.minutes) end end let(:point_params) do { locations: [ { geometry: { type: 'Point', coordinates: [1.0, 1.0] }, properties: { timestamp: '2025-01-17T21:03:01Z' } } ] } end describe 'GET /index' do context 'when regular version of points is requested' do it 'renders a successful response' do get api_v1_points_url(api_key: user.api_key) expect(response).to be_successful end it 'returns a list of points' do get api_v1_points_url(api_key: user.api_key) expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.size).to eq(15) end it 'returns a list of points with pagination' do get api_v1_points_url(api_key: user.api_key, page: 2, per_page: 10) expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.size).to eq(5) end it 'returns a list of points with pagination headers' do get api_v1_points_url(api_key: user.api_key, page: 2, per_page: 10) expect(response).to have_http_status(:ok) expect(response.headers['X-Current-Page']).to eq('2') expect(response.headers['X-Total-Pages']).to eq('2') end end context 'when slim version of points is requested' do it 'renders a successful response' do get api_v1_points_url(api_key: user.api_key, slim: 'true') expect(response).to be_successful end it 'returns a list of points' do get api_v1_points_url(api_key: user.api_key, slim: 'true') expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.size).to eq(15) end it 'returns a list of points with pagination' do get api_v1_points_url(api_key: user.api_key, slim: 'true', page: 2, per_page: 10) expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.size).to eq(5) end it 'returns a list of points with pagination headers' do get api_v1_points_url(api_key: user.api_key, slim: 'true', page: 2, per_page: 10) expect(response).to have_http_status(:ok) expect(response.headers['X-Current-Page']).to eq('2') expect(response.headers['X-Total-Pages']).to eq('2') end it 'returns a list of points with slim attributes' do get api_v1_points_url(api_key: user.api_key, slim: 'true') expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) json_response.each do |point| expect(point.keys).to eq(%w[id latitude longitude timestamp]) end end end context 'when order param is provided' do it 'returns points in ascending order' do get api_v1_points_url(api_key: user.api_key, order: 'asc') expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.first['timestamp']).to be < json_response.last['timestamp'] end it 'returns points in descending order' do get api_v1_points_url(api_key: user.api_key, order: 'desc') expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body) expect(json_response.first['timestamp']).to be > json_response.last['timestamp'] end end end describe 'POST /create' do it 'returns a successful response' do post "/api/v1/points?api_key=#{user.api_key}", params: point_params expect(response).to have_http_status(:ok) json_response = JSON.parse(response.body)['data'] expect(json_response.size).to be_positive expect(json_response.first['latitude']).to eq(1.0) expect(json_response.first['longitude']).to eq(1.0) expect(json_response.first['timestamp']).to be_an_instance_of(Integer) end context 'when user is inactive' do before do user.update(status: :inactive, active_until: 1.day.ago) end it 'returns an unauthorized response' do post "/api/v1/points?api_key=#{user.api_key}", params: point_params expect(response).to have_http_status(:unauthorized) end end end describe 'PUT /update' do it 'returns a successful response' do put "/api/v1/points/#{points.first.id}?api_key=#{user.api_key}", params: { point: { latitude: 1.0, longitude: 1.1 } } expect(response).to have_http_status(:success) end context 'when user is inactive' do before do user.update(status: :inactive, active_until: 1.day.ago) end it 'returns an unauthorized response' do put "/api/v1/points/#{points.first.id}?api_key=#{user.api_key}", params: { point: { latitude: 1.0, longitude: 1.1 } } expect(response).to have_http_status(:unauthorized) end end end describe 'DELETE /destroy' do it 'returns a successful response' do delete "/api/v1/points/#{points.first.id}?api_key=#{user.api_key}" expect(response).to have_http_status(:success) end context 'when user is inactive' do before do user.update(status: :inactive, active_until: 1.day.ago) end it 'returns an unauthorized response' do delete "/api/v1/points/#{points.first.id}?api_key=#{user.api_key}" expect(response).to have_http_status(:unauthorized) end end end end