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 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 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 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 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 } 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", environment: 'offline' 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 expect(report.dependency_names).to include('requests') end end end