# frozen_string_literal: true require 'spec_helper' RSpec.describe 'pipenv' do include_examples 'each report version', 'python', 'pipenv', 'pip-file-lock' context 'when a project depends on a version 6 Pipfile.lock' do let(:pipfile_lock_content) do JSON.pretty_generate({ "_meta": { "hash": { "sha256": '' }, "pipfile-spec": 6, "requires": { "python_version": '3.8' }, "sources": [{ "name": 'pypi', "url": 'https://pypi.org/simple', "verify_ssl": true }] }, "default": { "six": { "hashes": [], "index": 'pypi', "version": '==1.13.0' } }, "develop": {} }) end it 'produces a valid report' do runner.add_file('Pipfile.lock', pipfile_lock_content) report = runner.scan expect(report).to match_schema(version: '2.0') expect(report[:version]).not_to be_empty expect(report[:licenses]).not_to be_empty expect(report.dependency_names).to contain_exactly('six') end end context 'when a project depends on a version 3.2.1 Pipfile.lock' do let(:pipfile_lock_content) do JSON.pretty_generate({ "default": { "crayons": { "version": '==0.1.2', "hash": '' }, "requirements-parser": { "version": '==0.1.0', "hash": '' }, "pexpect": { "version": '==4.2.1', "hash": '' }, "delegator.py": { "version": '==0.0.8', "hash": '' }, "backports.shutil_get_terminal_size": { "version": '==1.0.0', "hash": '' }, "ptyprocess": { "version": '==0.5.1', "hash": '' }, "parse": { "version": '==1.6.6', "hash": '' }, "toml": { "version": '==0.9.2', "hash": '' }, "colorama": { "version": '==0.3.7', "hash": '' }, "requests": { "version": '==2.13.0', "hash": '' }, "click": { "version": '==6.7', "hash": '' } }, "develop": { "packaging": { "version": '==16.8', "hash": '' }, "pytest": { "version": '==3.0.6', "hash": '' }, "setuptools": { "version": '==34.0.2', "hash": '' }, "pyparsing": { "version": '==2.1.10', "hash": '' }, "py": { "version": '==1.4.32', "hash": '' }, "six": { "version": '==1.10.0', "hash": '' }, "appdirs": { "version": '==1.4.0', "hash": '' } }, "_meta": { "sources": [{ "url": 'https://pypi.python.org/simple', "verify_ssl": true }], "requires": {}, "Pipfile-sha256": '24f12b631b7c40b8c5eff934a1aef263ed04f5eaffb4acf4706442f3d23cba36' } }) end it 'produces a valid report' do runner.add_file('Pipfile.lock', pipfile_lock_content) report = runner.scan expect(report).to match_schema(version: '2.0') expect(report[:version]).not_to be_empty expect(report[:licenses]).not_to be_empty expect(report.dependency_names).to match_array([ 'backports.shutil_get_terminal_size', 'click', 'colorama', 'crayons', 'delegator.py', 'parse', 'pexpect', 'ptyprocess', 'requests', 'requirements-parser', 'toml' ]) end end context 'when a project depends on a version 5 Pipfile.lock' do let(:pipfile_lock_content) do JSON.pretty_generate({ "_meta": { "hash": { "sha256": '' }, "host-environment-markers": { "implementation_name": 'cpython', "implementation_version": '3.6.1', "os_name": 'posix', "platform_machine": 'x86_64', "platform_python_implementation": 'CPython', "platform_release": '16.7.0', "platform_system": 'Darwin', "platform_version": 'Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64', "python_full_version": '3.6.1', "python_version": '3.6', "sys_platform": 'darwin' }, "pipfile-spec": 5, "requires": {}, "sources": [{ "name": 'pypi', "url": 'https://pypi.python.org/simple', "verify_ssl": true }] }, "default": { "certifi": { "hashes": ['', ''], "version": '==2017.7.27.1' }, "chardet": { "hashes": ['', ''], "version": '==3.0.4' }, "idna": { "hashes": ['', ''], "version": '==2.6' }, "requests": { "hashes": ['', ''], "version": '==2.18.4' }, "urllib3": { "hashes": ['', ''], "version": '==1.22' } }, "develop": { "py": { "hashes": ['', ''], "version": '==1.4.34' }, "pytest": { "hashes": ['', ''], "version": '==3.2.2' } } }) end it 'produces a valid report' do runner.add_file('Pipfile.lock', pipfile_lock_content) report = runner.scan expect(report).to match_schema(version: '2.0') expect(report[:version]).not_to be_empty expect(report[:licenses]).not_to be_empty expect(report.dependency_names).to match_array(%w[ certifi chardet idna requests urllib3 ]) end end context 'when fetching metadata from a custom source' do let(:pipfile_lock_content) do JSON.pretty_generate({ "_meta": { "hash": { "sha256": '' }, "pipfile-spec": 6, "requires": { "python_version": '3.8' }, "sources": [{ "name": 'pypi', "url": 'https://test.pypi.org/simple', "verify_ssl": true }] }, "default": { "six": { "hashes": [], "index": 'pypi', "version": '==1.13.0' } }, "develop": {} }) end before do runner.add_file('Pipfile.lock', pipfile_lock_content) end it 'produces a valid report' do report = runner.scan expect(report).to match_schema(version: '2.0') expect(report[:licenses]).not_to be_empty expect(report[:dependencies].count).to be(1) expect(report.find('six')).not_to be_nil end end context 'when scanning a simple Pipfile project' do let(:lockfile_content) { fixture_file_content('python/simple-Pipfile.lock') } let(:lockfile_hash) { JSON.parse(lockfile_content) } before do runner.add_file('Pipfile', fixture_file_content('python/simple-Pipfile')) runner.add_file('Pipfile.lock', lockfile_content) end [2, 3].each do |version| context "when scanning a Python #{version} project" do let(:report) { runner.scan(env: { 'LM_PYTHON_VERSION' => version.to_s }) } specify { expect(report).to match_schema(version: '2.0') } it 'includes dependencies in the default group' do lockfile_hash['default'].keys.each do |key| expect(report.find(key)).not_to be_nil end end it 'excludes dependencies in the development group' do lockfile_hash['develop'].keys.each do |key| expect(report.find(key)).to be_nil end end end end end context 'when connecting to a private package repository with self signed certificate' do let(:index_url) { "https://#{private_pypi_host}/simple" } let(:bundle) { fixture_file_content('python/pypi.crt') } before do runner.add_file('Pipfile', fixture_file_content('python/airgap-Pipfile.erb', index_url: index_url)) runner.add_file('Pipfile.lock', fixture_file_content('python/airgap-Pipfile.lock.erb', index_url: index_url)) end it 'downloads the packages and trusts the certificate' do report = runner.scan(env: { 'ADDITIONAL_CA_CERT_BUNDLE' => bundle, 'PIP_INDEX_URL' => index_url }) expect(report).to match_schema(version: '2.0') expect(report.dependency_names).to include('requests') end end end