dawarich/spec/services/points/raw_data/verifier_spec.rb

169 lines
4.8 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Points::RawData::Verifier do
let(:user) { create(:user) }
let(:verifier) { described_class.new }
before do
allow(PointsChannel).to receive(:broadcast_to)
end
describe '#verify_specific_archive' do
let(:test_date) { 3.months.ago.beginning_of_month.utc }
let!(:points) do
create_list(:point, 5, user: user,
timestamp: test_date.to_i,
raw_data: { lon: 13.4, lat: 52.5 })
end
let(:archive) do
# Create archive
archiver = Points::RawData::Archiver.new
archiver.archive_specific_month(user.id, test_date.year, test_date.month)
Points::RawDataArchive.last
end
it 'verifies a valid archive successfully' do
expect(archive.verified_at).to be_nil
verifier.verify_specific_archive(archive.id)
archive.reload
expect(archive.verified_at).to be_present
end
it 'detects missing file' do
archive.file.purge
archive.reload
expect do
verifier.verify_specific_archive(archive.id)
end.not_to change { archive.reload.verified_at }
end
it 'detects point count mismatch' do
# Tamper with point count
archive.update_column(:point_count, 999)
expect do
verifier.verify_specific_archive(archive.id)
end.not_to change { archive.reload.verified_at }
end
it 'detects checksum mismatch' do
# Tamper with checksum
archive.update_column(:point_ids_checksum, 'invalid')
expect do
verifier.verify_specific_archive(archive.id)
end.not_to change { archive.reload.verified_at }
end
it 'still verifies successfully when points are deleted from database' do
# Force archive creation first
archive_id = archive.id
# Then delete one point from database
points.first.destroy
# Verification should still succeed - deleted points are acceptable
# (users should be able to delete their data without failing archive verification)
expect do
verifier.verify_specific_archive(archive_id)
end.to change { archive.reload.verified_at }.from(nil)
end
it 'detects raw_data mismatch between archive and database' do
# Force archive creation first
archive_id = archive.id
# Then modify raw_data in database after archiving
points.first.update_column(:raw_data, { lon: 999.0, lat: 999.0 })
expect do
verifier.verify_specific_archive(archive_id)
end.not_to change { archive.reload.verified_at }
end
it 'verifies raw_data matches between archive and database' do
# Ensure data hasn't changed
expect(points.first.raw_data).to eq({ 'lon' => 13.4, 'lat' => 52.5 })
verifier.verify_specific_archive(archive.id)
expect(archive.reload.verified_at).to be_present
end
end
describe '#verify_month' do
let(:test_date) { 3.months.ago.beginning_of_month.utc }
before do
# Create points
create_list(:point, 5, user: user,
timestamp: test_date.to_i,
raw_data: { lon: 13.4, lat: 52.5 })
# Archive them
archiver = Points::RawData::Archiver.new
archiver.archive_specific_month(user.id, test_date.year, test_date.month)
end
it 'verifies all archives for a month' do
expect(Points::RawDataArchive.where(verified_at: nil).count).to eq(1)
verifier.verify_month(user.id, test_date.year, test_date.month)
expect(Points::RawDataArchive.where(verified_at: nil).count).to eq(0)
end
end
describe '#call' do
let(:test_date) { 3.months.ago.beginning_of_month.utc }
before do
# Create points and archive
create_list(:point, 5, user: user,
timestamp: test_date.to_i,
raw_data: { lon: 13.4, lat: 52.5 })
archiver = Points::RawData::Archiver.new
archiver.archive_specific_month(user.id, test_date.year, test_date.month)
end
it 'verifies all unverified archives' do
expect(Points::RawDataArchive.where(verified_at: nil).count).to eq(1)
result = verifier.call
expect(result[:verified]).to eq(1)
expect(result[:failed]).to eq(0)
expect(Points::RawDataArchive.where(verified_at: nil).count).to eq(0)
end
it 'reports failures' do
# Tamper with archive
Points::RawDataArchive.last.update_column(:point_count, 999)
result = verifier.call
expect(result[:verified]).to eq(0)
expect(result[:failed]).to eq(1)
end
it 'skips already verified archives' do
# Verify once
verifier.call
# Try to verify again with a new verifier instance
new_verifier = Points::RawData::Verifier.new
result = new_verifier.call
expect(result[:verified]).to eq(0)
expect(result[:failed]).to eq(0)
end
end
end