gradle/spec/dependabot/gradle/file_parser/repositories_finder_spec.rb
# typed: false
# frozen_string_literal: true

require "spec_helper"
require "dependabot/dependency_file"
require "dependabot/gradle/file_parser/repositories_finder"

RSpec.describe Dependabot::Gradle::FileParser::RepositoriesFinder do
  let(:finder) do
    described_class.new(
      dependency_files: dependency_files,
      target_dependency_file: target_dependency_file
    )
  end

  let(:dependency_files) { [buildfile] }
  let(:target_dependency_file) { buildfile }
  let(:buildfile) do
    Dependabot::DependencyFile.new(
      name: "build.gradle",
      content: fixture("buildfiles", buildfile_fixture_name)
    )
  end
  let(:buildfile_fixture_name) { "basic_build.gradle" }

  describe "#repository_urls" do
    subject(:repository_urls) { finder.repository_urls }

    context "when there are no repository declarations" do
      let(:buildfile_fixture_name) { "basic_build.gradle" }

      it { is_expected.to eq(["https://repo.maven.apache.org/maven2"]) }
    end

    context "when there are repository declarations" do
      let(:buildfile_fixture_name) { "custom_repos_build.gradle" }

      it "includes the additional declarations" do
        expect(repository_urls).to match_array(
          %w(
            https://jcenter.bintray.com
            https://dl.bintray.com/magnusja/maven
            https://maven.google.com
          )
        )
      end

      context "with a script plugin" do
        let(:dependency_files) { [buildfile, script_plugin] }
        let(:buildfile_fixture_name) { "with_dependency_script.gradle" }
        let(:script_plugin) do
          Dependabot::DependencyFile.new(
            name: "gradle/dependencies.gradle",
            content: fixture("script_plugins", "dependencies.gradle")
          )
        end

        it "includes the additional declarations" do
          expect(repository_urls).to match_array(
            %w(
              https://jcenter.bintray.com
              https://plugins.gradle.org/m2
              https://repo.example.com
            )
          )
        end
      end

      context "when there are subproject declarations" do
        let(:buildfile_fixture_name) { "subproject_repos.gradle" }

        it "doesn't include the subproject declarations" do
          expect(repository_urls)
            .to match_array(
              %w(
                https://jcenter.bintray.com
                https://dl.bintray.com/magnusja/maven
                https://maven.google.com
                https://plugins.gradle.org/m2
              )
            )
        end

        context "when the declaration is a subproject" do
          let(:dependency_files) { [buildfile, subproject] }
          let(:target_dependency_file) { subproject }
          let(:subproject) do
            Dependabot::DependencyFile.new(
              name: "myapp/build.gradle",
              content: fixture("buildfiles", "basic_build.gradle")
            )
          end

          it "includes the subproject declarations, too" do
            expect(repository_urls).to match_array(
              %w(
                https://jcenter.bintray.com
                https://dl.bintray.com/magnusja/maven
                https://maven.google.com
                https://plugins.gradle.org/m2
              )
            )
          end
        end
      end

      context "when the eval code within the declaration" do
        let(:buildfile_fixture_name) { "eval_repo_build.gradle" }

        it "ignores the repo that needs evaling" do
          expect(repository_urls).to match_array(
            %w(
              https://jcenter.bintray.com
              https://maven.google.com
            )
          )
        end
      end

      context "with dependencyResolutionManagement in the settings file" do
        let(:dependency_files) { [buildfile, settings_file] }
        let(:settings_file) do
          Dependabot::DependencyFile.new(
            name: "settings.gradle",
            content: fixture("settings_files", settings_file_fixture_name)
          )
        end
        let(:settings_file_fixture_name) { "dependency_resolution_management.gradle" }

        it "finds the repositories" do
          expect(repository_urls).to match_array(
            %w(
              https://dependency_resolution_management.example.com
              https://jcenter.bintray.com
              https://dl.bintray.com/magnusja/maven
              https://maven.google.com
            )
          )
        end
      end

      context "when the declaration gets URLs from a variable" do
        let(:buildfile_fixture_name) { "variable_repos_build.gradle" }

        it "includes the additional declarations" do
          expect(repository_urls).to match_array(
            %w(
              https://jcenter.bintray.com
              https://dl.bintray.com/magnusja/maven
              https://maven.google.com
            )
          )
        end
      end

      context "when the declaration uses an assignment operator" do
        let(:buildfile_fixture_name) { "custom_repos_build_assignment.gradle" }

        it "includes the additional declarations" do
          expect(repository_urls).to match_array(
            %w(
              https://jcenter.bintray.com
              https://hub.spigotmc.org/nexus/content/repositories/snapshots
            )
          )
        end
      end

      context "when the declaration uses an assignment operator and a strict URI" do
        let(:buildfile_fixture_name) { "custom_repos_build_assignment_uri.gradle" }

        it "includes the additional declarations" do
          expect(repository_urls).to match_array(
            %w(
              https://maven.google.com
              https://uri-helper.com
              https://java-constructor.com
            )
          )
        end
      end

      context "with kotlin" do
        let(:buildfile_fixture_name) { "root_build.gradle.kts" }

        it "includes the additional declarations" do
          expect(repository_urls).to match_array(
            %w(
              https://jcenter.bintray.com
              https://dl.bintray.com/magnusja/maven
              https://kotlin.bintray.com/kotlinx
              https://maven.google.com
            )
          )
        end
      end
    end
  end
end
