require 'rails_helper'

RSpec.describe GpxParser do
  let(:filename) { 'one-track.gpx' }

  let(:user) do
    User.create!(
      email: 'user@example.com',
      username: 'username',
      password: 'password'
    )
  end

  let(:track) do
    user.tracks.build(name: 'My Track').tap do |track|
      track.gpx.attach(
        io: File.open(file_fixture(filename)),
        filename: filename
      )

      track.save!
    end
  end

  describe '#parse!' do
    it 'parses coordinates, distance, and track names' do
      result = GpxParser.parse!(track: track)

      expect(result.coordinates.count).to eq(1)
      expect(result.distance_in_miles).to eq(17.8)
      expect(result.track_names).to include('Track 2')
    end

    context 'when gpx has multiple tracks' do
      let(:filename) { 'two-tracks.gpx' }

      it 'parses coordinates and total distance of all tracks' do
        result = GpxParser.parse!(track: track)

        expect(result.coordinates.count).to eq(2)
        expect(result.distance_in_miles).to eq(17.9)
      end

      it 'downloads the gpx a single time' do
        expect(GPX::GPXFile).to receive(:new).once.and_call_original

        GpxParser.parse!(track: track)
      end
    end

    context 'when the track in the gpx is missing a name' do
      let(:filename) { 'track-without-name.gpx' }

      it 'defaults to the track name' do
        result = GpxParser.parse!(track: track)

        expect(result.coordinates[0][0]).to eq(track.name)
      end
    end

    context 'when gpx has waypoints' do
      let(:filename) { 'track-with-waypoints.gpx' }

      it 'parses the waypoints' do
        result = GpxParser.parse!(track: track)

        expect(result.waypoints.count).to eq(2)
      end
    end

    context 'when the attached file is not a gpx' do
      let(:filename) { 'not-a-gpx.png' }

      it 'raises an exception' do
        expect {
          GpxParser.parse!(track: track)
        }.to raise_error(GpxParser::InvalidGpxError)
      end
    end
  end
end
