2024-04-26 12:59:58 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2022-04-06 14:46:10 -04:00
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
|
|
RSpec.describe User, type: :model do
|
2024-04-02 17:20:25 -04:00
|
|
|
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) }
|
2024-05-25 07:26:56 -04:00
|
|
|
it { is_expected.to have_many(:tracked_points).class_name('Point').dependent(:destroy) }
|
2024-06-12 14:29:38 -04:00
|
|
|
it { is_expected.to have_many(:exports).dependent(:destroy) }
|
2024-07-04 16:20:12 -04:00
|
|
|
it { is_expected.to have_many(:notifications).dependent(:destroy) }
|
2024-07-21 14:09:42 -04:00
|
|
|
it { is_expected.to have_many(:areas).dependent(:destroy) }
|
2024-07-21 14:32:29 -04:00
|
|
|
it { is_expected.to have_many(:visits).dependent(:destroy) }
|
2024-08-25 14:19:02 -04:00
|
|
|
it { is_expected.to have_many(:places).through(:visits) }
|
2024-11-27 14:14:17 -05:00
|
|
|
it { is_expected.to have_many(:trips).dependent(:destroy) }
|
2024-04-02 17:20:25 -04:00
|
|
|
end
|
|
|
|
|
|
2025-02-19 15:23:11 -05:00
|
|
|
describe 'enums' do
|
|
|
|
|
it { is_expected.to define_enum_for(:status).with_values(inactive: 0, active: 1) }
|
|
|
|
|
end
|
|
|
|
|
|
2024-04-04 14:14:11 -04:00
|
|
|
describe 'callbacks' do
|
|
|
|
|
describe '#create_api_key' do
|
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
|
|
|
|
it 'creates api key' do
|
|
|
|
|
expect(user.api_key).to be_present
|
|
|
|
|
end
|
|
|
|
|
end
|
2025-02-19 15:23:11 -05:00
|
|
|
|
|
|
|
|
describe '#activate' do
|
|
|
|
|
context 'when self-hosted' do
|
2025-04-04 15:12:42 -04:00
|
|
|
let!(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
2025-02-24 18:16:42 -05:00
|
|
|
|
2025-02-19 15:23:11 -05:00
|
|
|
before do
|
|
|
|
|
allow(DawarichSettings).to receive(:self_hosted?).and_return(true)
|
|
|
|
|
end
|
|
|
|
|
|
2025-02-24 18:16:42 -05:00
|
|
|
it 'activates user after creation' do
|
|
|
|
|
expect(user.active?).to be_truthy
|
2025-04-04 15:12:42 -04:00
|
|
|
expect(user.active_until).to be_within(1.minute).of(1000.years.from_now)
|
2025-02-19 15:23:11 -05:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when not self-hosted' do
|
|
|
|
|
before do
|
|
|
|
|
allow(DawarichSettings).to receive(:self_hosted?).and_return(false)
|
|
|
|
|
end
|
|
|
|
|
|
2025-04-04 15:12:42 -04:00
|
|
|
it 'does not activate user' do
|
|
|
|
|
user = create(:user, status: :inactive, active_until: 1.day.ago)
|
|
|
|
|
|
2025-02-24 18:16:42 -05:00
|
|
|
expect(user.active?).to be_falsey
|
2025-04-04 15:12:42 -04:00
|
|
|
expect(user.active_until).to be_within(1.minute).of(1.day.ago)
|
2025-02-19 15:23:11 -05:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2025-03-12 15:26:53 -04:00
|
|
|
|
|
|
|
|
describe '#import_sample_points' do
|
|
|
|
|
before do
|
2025-03-12 16:19:48 -04:00
|
|
|
ENV['IMPORT_SAMPLE_POINTS'] = 'true'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
after do
|
|
|
|
|
ENV['IMPORT_SAMPLE_POINTS'] = nil
|
2025-03-12 15:26:53 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'creates a sample import and enqueues an import job' do
|
2025-03-12 16:19:48 -04:00
|
|
|
user = create(:user)
|
|
|
|
|
|
|
|
|
|
expect(user.imports.count).to eq(1)
|
|
|
|
|
expect(user.imports.first.name).to eq('DELETE_ME_this_is_a_demo_import_DELETE_ME')
|
|
|
|
|
expect(user.imports.first.source).to eq('gpx')
|
|
|
|
|
|
2025-04-04 14:14:44 -04:00
|
|
|
expect(Import::ProcessJob).to have_been_enqueued.with(user.imports.first.id)
|
2025-03-12 15:26:53 -04:00
|
|
|
end
|
|
|
|
|
end
|
2024-04-04 14:14:11 -04:00
|
|
|
end
|
|
|
|
|
|
2024-04-02 17:20:25 -04:00
|
|
|
describe 'methods' do
|
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
2024-04-26 12:59:58 -04:00
|
|
|
describe '#countries_visited' do
|
|
|
|
|
subject { user.countries_visited }
|
|
|
|
|
|
|
|
|
|
let!(:stat1) { create(:stat, user:, toponyms: [{ 'country' => 'Germany' }]) }
|
|
|
|
|
let!(:stat2) { create(:stat, user:, toponyms: [{ 'country' => 'France' }]) }
|
|
|
|
|
|
|
|
|
|
it 'returns array of countries' do
|
2025-03-04 15:16:45 -05:00
|
|
|
expect(subject).to include('Germany', 'France')
|
|
|
|
|
expect(subject.count).to eq(2)
|
2024-04-26 12:59:58 -04:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#cities_visited' do
|
|
|
|
|
subject { user.cities_visited }
|
|
|
|
|
|
|
|
|
|
let!(:stat1) { create(:stat, user:, toponyms: [{ 'cities' => [{ 'city' => 'Berlin' }] }]) }
|
|
|
|
|
let!(:stat2) { create(:stat, user:, toponyms: [{ 'cities' => [{ 'city' => 'Paris' }] }]) }
|
|
|
|
|
|
|
|
|
|
it 'returns array of cities' do
|
|
|
|
|
expect(subject).to eq(%w[Berlin Paris])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-08-28 17:54:00 -04:00
|
|
|
describe '#total_distance' do
|
|
|
|
|
subject { user.total_distance }
|
2024-04-02 17:20:25 -04:00
|
|
|
|
2024-04-26 12:59:58 -04:00
|
|
|
let!(:stat1) { create(:stat, user:, distance: 10) }
|
|
|
|
|
let!(:stat2) { create(:stat, user:, distance: 20) }
|
2024-04-02 17:20:25 -04:00
|
|
|
|
|
|
|
|
it 'returns sum of distances' do
|
|
|
|
|
expect(subject).to eq(30)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#total_countries' do
|
|
|
|
|
subject { user.total_countries }
|
|
|
|
|
|
2024-04-26 12:59:58 -04:00
|
|
|
let!(:stat) { create(:stat, user:, toponyms: [{ 'country' => 'Country' }]) }
|
2024-04-02 17:20:25 -04:00
|
|
|
|
|
|
|
|
it 'returns number of countries' do
|
|
|
|
|
expect(subject).to eq(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#total_cities' do
|
|
|
|
|
subject { user.total_cities }
|
|
|
|
|
|
2024-04-26 12:59:58 -04:00
|
|
|
let!(:stat) do
|
|
|
|
|
create(
|
|
|
|
|
:stat,
|
|
|
|
|
user:,
|
|
|
|
|
toponyms: [
|
|
|
|
|
{ 'cities' => [], 'country' => nil },
|
2024-07-12 16:11:42 -04:00
|
|
|
{ 'cities' => [{ 'city' => 'Berlin', 'points' => 64, 'timestamp' => 1_710_446_806, 'stayed_for' => 8772 }],
|
|
|
|
|
'country' => 'Germany' }
|
2024-04-26 12:59:58 -04:00
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
end
|
2024-04-02 17:20:25 -04:00
|
|
|
|
|
|
|
|
it 'returns number of cities' do
|
|
|
|
|
expect(subject).to eq(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-12-02 08:44:22 -05:00
|
|
|
describe '#total_reverse_geocoded_points' do
|
|
|
|
|
subject { user.total_reverse_geocoded_points }
|
2024-04-02 17:20:25 -04:00
|
|
|
|
2024-12-02 08:44:22 -05:00
|
|
|
let!(:reverse_geocoded_point) { create(:point, :reverse_geocoded, user:) }
|
|
|
|
|
let!(:not_reverse_geocoded_point) { create(:point, user:, reverse_geocoded_at: nil) }
|
2024-04-02 17:20:25 -04:00
|
|
|
|
|
|
|
|
it 'returns number of reverse geocoded points' do
|
|
|
|
|
expect(subject).to eq(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-12-02 08:44:22 -05:00
|
|
|
|
|
|
|
|
describe '#total_reverse_geocoded_points_without_data' do
|
|
|
|
|
subject { user.total_reverse_geocoded_points_without_data }
|
|
|
|
|
|
|
|
|
|
let!(:reverse_geocoded_point) { create(:point, :reverse_geocoded, :with_geodata, user:) }
|
|
|
|
|
let!(:reverse_geocoded_point_without_data) { create(:point, :reverse_geocoded, user:, geodata: {}) }
|
|
|
|
|
|
|
|
|
|
it 'returns number of reverse geocoded points without data' do
|
|
|
|
|
expect(subject).to eq(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-12-10 14:15:42 -05:00
|
|
|
|
2024-12-06 11:32:45 -05:00
|
|
|
describe '#years_tracked' do
|
2025-01-20 11:59:13 -05:00
|
|
|
let!(:points) do
|
|
|
|
|
(1..3).map do |i|
|
|
|
|
|
create(:point, user:, timestamp: DateTime.new(2024, 1, 1, 5, 0, 0) + i.minutes)
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-12-06 11:32:45 -05:00
|
|
|
|
|
|
|
|
it 'returns years tracked' do
|
2024-12-16 09:10:46 -05:00
|
|
|
expect(user.years_tracked).to eq([{ year: 2024, months: ['Jan'] }])
|
2024-12-06 11:32:45 -05:00
|
|
|
end
|
|
|
|
|
end
|
2025-04-04 14:14:44 -04:00
|
|
|
|
|
|
|
|
describe '#can_subscribe?' do
|
|
|
|
|
context 'when Dawarich is self-hosted' do
|
|
|
|
|
before do
|
|
|
|
|
allow(DawarichSettings).to receive(:self_hosted?).and_return(true)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when user is active' do
|
2025-04-04 15:39:59 -04:00
|
|
|
let!(:user) { create(:user, status: :active, active_until: 1000.years.from_now) }
|
2025-04-04 14:14:44 -04:00
|
|
|
|
|
|
|
|
it 'returns false' do
|
|
|
|
|
expect(user.can_subscribe?).to be_falsey
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when user is inactive' do
|
2025-04-04 15:39:59 -04:00
|
|
|
let(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
2025-04-04 14:14:44 -04:00
|
|
|
|
|
|
|
|
it 'returns false' do
|
|
|
|
|
expect(user.can_subscribe?).to be_falsey
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when Dawarich is not self-hosted' do
|
|
|
|
|
before do
|
|
|
|
|
allow(DawarichSettings).to receive(:self_hosted?).and_return(false)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when user is active' do
|
2025-04-04 15:39:59 -04:00
|
|
|
let(:user) { create(:user, status: :active, active_until: 1000.years.from_now) }
|
2025-04-04 14:14:44 -04:00
|
|
|
|
|
|
|
|
it 'returns false' do
|
|
|
|
|
expect(user.can_subscribe?).to be_falsey
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when user is inactive' do
|
2025-04-04 15:39:59 -04:00
|
|
|
let(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
2025-04-04 14:14:44 -04:00
|
|
|
|
|
|
|
|
it 'returns true' do
|
|
|
|
|
expect(user.can_subscribe?).to be_truthy
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-04-02 17:20:25 -04:00
|
|
|
end
|
2022-04-06 14:46:10 -04:00
|
|
|
end
|