# frozen_string_literal: true 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 } let(:user) { create(:user) } describe '.year_cities_and_countries' do subject { described_class.year_cities_and_countries(year, user) } let(:timestamp) { DateTime.new(year, 1, 1, 0, 0, 0) } before do stub_const('MIN_MINUTES_SPENT_IN_CITY', 60) end context 'when there are points' do let!(:points) do [ create(:point, user:, city: 'Berlin', country: 'Germany', timestamp:), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 10.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 20.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 30.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 40.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 50.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 60.minutes), create(:point, user:, city: 'Berlin', country: 'Germany', timestamp: timestamp + 70.minutes), create(:point, user:, city: 'Brugges', country: 'Belgium', timestamp: timestamp + 80.minutes), create(:point, user:, city: 'Brugges', country: 'Belgium', timestamp: timestamp + 90.minutes) ] end it 'returns countries and cities' do # User spent only 20 minutes in Brugges, so it should not be included expect(subject).to eq(countries: 2, cities: 1) 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:) create(:stat, year: 2020, 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:, month: 1, 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, user:, latitude: 1, longitude: 1, timestamp: DateTime.new(year, 1, 1, 1)) create(:point, user:, 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:, 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, user) } 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:, month: 1, distance: 100, user:) create(:stat, year:, month: 2, distance: 200, 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