mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Add some unit tests
This commit is contained in:
parent
5544bcd5ff
commit
48962e87e8
7 changed files with 286 additions and 17 deletions
|
|
@ -5,20 +5,16 @@ class Stat < ApplicationRecord
|
|||
|
||||
belongs_to :user
|
||||
|
||||
def timespan
|
||||
DateTime.new(year, month).beginning_of_month..DateTime.new(year, month).end_of_month
|
||||
end
|
||||
|
||||
def distance_by_day
|
||||
timespan.to_a.map.with_index(1) do |day, index|
|
||||
beginning_of_day = day.beginning_of_day.to_i
|
||||
end_of_day = day.end_of_day.to_i
|
||||
|
||||
data = { day: index, distance: 0 }
|
||||
|
||||
# We have to filter by user as well
|
||||
points = Point.where(timestamp: beginning_of_day..end_of_day)
|
||||
|
||||
data = { day: index, distance: 0 }
|
||||
|
||||
points.each_cons(2) do |point1, point2|
|
||||
distance = Geocoder::Calculations.distance_between(
|
||||
[point1.latitude, point1.longitude], [point2.latitude, point2.longitude]
|
||||
|
|
@ -49,12 +45,18 @@ class Stat < ApplicationRecord
|
|||
|
||||
data = CountriesAndCities.new(points).call
|
||||
|
||||
{ countries: data.count, cities: data.sum { |country| country[:cities].count } }
|
||||
{ countries: data.map { _1[:country] }.uniq.count, cities: data.sum { |country| country[:cities].count } }
|
||||
end
|
||||
|
||||
def self.years
|
||||
starting_year = pluck(:year).uniq.min || Time.current.year
|
||||
starting_year = select(:year).min&.year || Time.current.year
|
||||
|
||||
(starting_year..Time.current.year).to_a.reverse
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def timespan
|
||||
DateTime.new(year, month).beginning_of_month..DateTime.new(year, month).end_of_month
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
FactoryBot.define do
|
||||
factory :import do
|
||||
user_id { "" }
|
||||
user
|
||||
name { 'APRIL_2013.json' }
|
||||
source { 1 }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ FactoryBot.define do
|
|||
raw_data { "" }
|
||||
tracker_id { "MyString" }
|
||||
import_id { "" }
|
||||
city { "MyString" }
|
||||
country { "MyString" }
|
||||
city { nil }
|
||||
country { nil }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
61
spec/jobs/reverse_geocoding_job_spec.rb
Normal file
61
spec/jobs/reverse_geocoding_job_spec.rb
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ReverseGeocodingJob, type: :job do
|
||||
describe '#perform' do
|
||||
subject(:perform) { described_class.new.perform(point.id) }
|
||||
|
||||
let(:point) { create(:point) }
|
||||
|
||||
before do
|
||||
allow(Geocoder).to receive(:search).and_return([double(city: 'City', country: 'Country')])
|
||||
end
|
||||
|
||||
context 'when REVERSE_GEOCODING_ENABLED is false' do
|
||||
before { stub_const('REVERSE_GEOCODING_ENABLED', false) }
|
||||
|
||||
it 'does not update point' do
|
||||
expect { perform }.not_to change { point.reload.city }
|
||||
end
|
||||
|
||||
it 'does not call Geocoder' do
|
||||
perform
|
||||
|
||||
expect(Geocoder).not_to have_received(:search)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when REVERSE_GEOCODING_ENABLED is true' do
|
||||
before { stub_const('REVERSE_GEOCODING_ENABLED', true) }
|
||||
|
||||
it 'updates point with city and country' do
|
||||
expect { perform }.to change { point.reload.city }.from(nil)
|
||||
end
|
||||
|
||||
it 'calls Geocoder' do
|
||||
perform
|
||||
|
||||
expect(Geocoder).to have_received(:search).with([point.latitude, point.longitude])
|
||||
end
|
||||
|
||||
context 'when point has city and country' do
|
||||
let(:point) { create(:point, city: 'City', country: 'Country') }
|
||||
|
||||
before do
|
||||
allow(Geocoder).to receive(:search).and_return(
|
||||
[double(city: 'Another city', country: 'Some country')]
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not update point' do
|
||||
expect { perform }.not_to change { point.reload.city }
|
||||
end
|
||||
|
||||
it 'does not call Geocoder' do
|
||||
perform
|
||||
|
||||
expect(Geocoder).not_to have_received(:search)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,20 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatCreatingJob, type: :job do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
describe '#perform' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
subject { described_class.perform_now([user.id]) }
|
||||
|
||||
before do
|
||||
allow(CreateStats).to receive(:new).and_call_original
|
||||
allow_any_instance_of(CreateStats).to receive(:call)
|
||||
end
|
||||
|
||||
it 'creates a stat' do
|
||||
subject
|
||||
|
||||
expect(CreateStats).to have_received(:new).with([user.id])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,135 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Stat, type: :model do
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:user) }
|
||||
it { is_expected.to validate_presence_of(:year) }
|
||||
it { is_expected.to validate_presence_of(:month) }
|
||||
end
|
||||
|
||||
describe 'methods' do
|
||||
let(:year) { 2021 }
|
||||
|
||||
describe '.year_cities_and_countries' do
|
||||
subject { described_class.year_cities_and_countries(year) }
|
||||
|
||||
before do
|
||||
stub_const('MINIMUM_POINTS_IN_CITY', 1)
|
||||
end
|
||||
|
||||
context 'when there are points' do
|
||||
let!(:points) do
|
||||
create_list(:point, 3, city: 'City', country: 'Country', timestamp: DateTime.new(year, 1))
|
||||
create_list(:point, 2, city: 'Some City', country: 'Another country', timestamp: DateTime.new(year, 2))
|
||||
end
|
||||
|
||||
|
||||
it 'returns countries and cities' do
|
||||
expect(subject).to eq(countries: 2, cities: 2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no points' do
|
||||
it 'returns countries and cities' do
|
||||
expect(subject).to eq(countries: 0, cities: 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.years' do
|
||||
subject { described_class.years }
|
||||
|
||||
context 'when there are no stats' do
|
||||
it 'returns years' do
|
||||
expect(subject).to eq([Time.current.year])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are stats' do
|
||||
let(:user) { create(:user) }
|
||||
let(:expected_years) { (year..Time.current.year).to_a.reverse }
|
||||
|
||||
before do
|
||||
create(:stat, year: 2021, user: user)
|
||||
create(:stat, year: 2020, user: user)
|
||||
end
|
||||
|
||||
it 'returns years' do
|
||||
expect(subject).to eq(expected_years)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#distance_by_day' do
|
||||
subject { stat.distance_by_day }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:stat) { create(:stat, year: year, month: 1, user: user) }
|
||||
let(:expected_distance) do
|
||||
# 31 day of January
|
||||
(1..31).map { |day| [day, 0] }
|
||||
end
|
||||
|
||||
context 'when there are points' do
|
||||
let!(:points) do
|
||||
create(:point, latitude: 1, longitude: 1, timestamp: DateTime.new(year, 1, 1, 1))
|
||||
create(:point, latitude: 2, longitude: 2, timestamp: DateTime.new(year, 1, 1, 2))
|
||||
end
|
||||
|
||||
before { expected_distance[0][1] = 157.23 }
|
||||
|
||||
it 'returns distance by day' do
|
||||
expect(subject).to eq(expected_distance)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no points' do
|
||||
it 'returns distance by day' do
|
||||
expect(subject).to eq(expected_distance)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#timespan' do
|
||||
subject { stat.send(:timespan) }
|
||||
|
||||
let(:stat) { build(:stat, year: year, month: 1) }
|
||||
let(:expected_timespan) { DateTime.new(year, 1).beginning_of_month..DateTime.new(year, 1).end_of_month }
|
||||
|
||||
it 'returns timespan' do
|
||||
expect(subject).to eq(expected_timespan)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#self.year_distance' do
|
||||
subject { described_class.year_distance(year) }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:expected_distance) do
|
||||
(1..12).map { |month| [Date::MONTHNAMES[month], 0] }
|
||||
end
|
||||
|
||||
context 'when there are stats' do
|
||||
let!(:stats) do
|
||||
create(:stat, year: year, month: 1, distance: 100, user: user)
|
||||
create(:stat, year: year, month: 2, distance: 200, user: user)
|
||||
end
|
||||
|
||||
before do
|
||||
expected_distance[0][1] = 100
|
||||
expected_distance[1][1] = 200
|
||||
end
|
||||
|
||||
it 'returns year distance' do
|
||||
expect(subject).to eq(expected_distance)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no stats' do
|
||||
it 'returns year distance' do
|
||||
expect(subject).to eq(expected_distance)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,68 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe User, type: :model do
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_many(:imports).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:points).through(:imports) }
|
||||
it { is_expected.to have_many(:stats) }
|
||||
end
|
||||
|
||||
describe 'methods' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
xdescribe '#export_data' do
|
||||
subject { user.export_data }
|
||||
|
||||
let(:import) { create(:import, user: user) }
|
||||
let(:point) { create(:point, import: import) }
|
||||
|
||||
it 'returns json' do
|
||||
expect(subject).to include(user.email)
|
||||
expect(subject).to include('dawarich-export')
|
||||
expect(subject).to include(point.attributes.except('raw_data', 'id', 'created_at', 'updated_at', 'country', 'city', 'import_id').to_json)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#total_km' do
|
||||
subject { user.total_km }
|
||||
|
||||
let!(:stat_1) { create(:stat, user: user, distance: 10) }
|
||||
let!(:stat_2) { create(:stat, user: user, distance: 20) }
|
||||
|
||||
it 'returns sum of distances' do
|
||||
expect(subject).to eq(30)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#total_countries' do
|
||||
subject { user.total_countries }
|
||||
|
||||
let!(:stat) { create(:stat, user: user, toponyms: [{ 'country' => 'Country' }]) }
|
||||
|
||||
it 'returns number of countries' do
|
||||
expect(subject).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#total_cities' do
|
||||
subject { user.total_cities }
|
||||
|
||||
let!(:stat) { create(:stat, user: user, toponyms: [{ 'city' => 'City' }]) }
|
||||
|
||||
it 'returns number of cities' do
|
||||
expect(subject).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#total_reverse_geocoded' do
|
||||
subject { user.total_reverse_geocoded }
|
||||
|
||||
let(:import) { create(:import, user: user) }
|
||||
let!(:point) { create(:point, country: 'Country', city: 'City', import: import) }
|
||||
|
||||
it 'returns number of reverse geocoded points' do
|
||||
expect(subject).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue