diff --git a/README.md b/README.md
index 5bfc9a8..b3f2134 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Scanning 19 packages...
 
 ## Installation
 
-The easiest way to install the `export` plugin is via the `plugin add` command of Poetry.
+The easiest way to install the `audit` plugin is via the `plugin add` command of Poetry.
 
 ```bash
 poetry plugin add poetry-audit-plugin
@@ -38,20 +38,36 @@ pip install poetry-audit-plugin
 * `--json`: Export the result in JSON format.
 
 * `--ignore-code`: Ignore some vulnerabilities IDs. Receive a list of IDs. For example:
+
 ```bash
 poetry audit --ignore-code=CVE-2022-42969,CVE-2020-10684
 ```
 
 * `--ignore-package`: Ignore some packages. Receive a list of packages. For example:
+
 ```bash
 poetry audit --json --ignore-package=py,ansible-tower-cli
 ```
+
+* `--proxy-protocol`, `--proxy-host`, `--proxy-port`: Proxy to access Safety DB. For example:
+
+```bash
+poetry audit --proxy-protocol=http --proxy-host=localhost --proxy-port=3128
+```
+
+* `--cache-sec`: How long Safety DB can be cached locally. For example:
+
+```bash
+poetry audit --cache-sec=60
+```
+
 ## Exit codes
 
 `poetry audit` will exit with a code indicating its status.
 
 * `0`: Vulnerabilities were not found.
 * `1`: One or more vulnerabilities were found.
+* Others: Something wrong happened.
 
 ## Develop poetry-audit-plugin
 
@@ -69,6 +85,7 @@ Once you've done it, you can start developing poetry-audit-plugin. You can use t
 
 ```sh
 cd tests/assets/no_vulnerabilities
+poetry shell
 poetry audit
 ```
 
diff --git a/poetry_audit_plugin/command.py b/poetry_audit_plugin/command.py
index c3968ec..49cb6e0 100644
--- a/poetry_audit_plugin/command.py
+++ b/poetry_audit_plugin/command.py
@@ -1,16 +1,24 @@
+import copy
 import json
 import sys
-from typing import Any, Dict, List
+from typing import Any, Dict, List, Tuple
 
 from cleo.helpers import option
 from poetry.console.commands.command import Command
 
 from poetry_audit_plugin import __version__
+from poetry_audit_plugin.constants import (
+    EXIT_CODE_OK,
+    EXIT_CODE_OPTION_INVALID,
+    EXIT_CODE_VULNERABILITY_FOUND,
+)
+from poetry_audit_plugin.errors import SafetyDBAccessError, SafetyDBSessionBuildError
 from poetry_audit_plugin.safety import (
     Package,
+    Vulnerability,
     VulnerablePackage,
+    build_safety_db_session,
     check_vulnerable_packages,
-    suppress_vulnerable_packages,
 )
 
 
@@ -19,17 +27,59 @@ class AuditCommand(Command):
     description = "Check vulnerabilities in dependencies"
 
     options = [
-        option("json", None, "Generate a JSON payload with the information of vulnerable packages.", flag=True),
-        option("ignore-code", None, "Ignore specified vulnerability codes", flag=False),
-        option("ignore-package", None, "Ignore specified packages", flag=False),
+        option(
+            long_name="json",
+            description="Generate a JSON payload with the information of vulnerable packages.",
+            flag=True,
+        ),
+        option(
+            long_name="ignore-code",
+            description="Ignore specified vulnerability codes.",
+            flag=False,
+        ),
+        option(
+            long_name="ignore-package",
+            description="Ignore specified packages.",
+            flag=False,
+        ),
+        option(
+            long_name="proxy-protocol",
+            description="Protocol of proxy to access Safety DB.",
+            flag=False,
+            value_required=False,
+            default="http",
+        ),
+        option(
+            long_name="proxy-host",
+            description="Host of proxy to access Safety DB.",
+            flag=False,
+            value_required=False,
+        ),
+        option(
+            long_name="proxy-port",
+            description="Port of proxy to access Safety DB.",
+            flag=False,
+            value_required=False,
+            default="80",
+        ),
+        option(
+            long_name="cache-sec",
+            description="How long Safety DB can be cached locally.",
+            flag=False,
+            value_required=False,
+            default="0",
+        ),
     ]
 
     def handle(self) -> None:
         self.is_quiet = self.option("json")
 
+        self.line("<b># poetry audit report</b>")
+        self.line("")
+
+        self.validate_options()
         self.validate_lock_file()
 
-        self.line("<b># poetry audit report</b>")
         self.line("<info>Loading...</info>")
 
         locked_repo = self.poetry.locker.locked_repository()
@@ -40,22 +90,45 @@ def handle(self) -> None:
         self.line(f"<info>Scanning {len(packages)} packages...</info>")
         self.line("")
 
-        all_vulnerable_packages = check_vulnerable_packages(packages)
-
         ignored_packages: List[str] = self.option("ignore-package").split(",") if self.option("ignore-package") else []
         ignored_codes: List[str] = self.option("ignore-code").split(",") if self.option("ignore-code") else []
         is_ignore = bool(len(ignored_packages) or len(ignored_codes))
-        vulnerable_packages, amount_of_ignored_vulnerabilities = suppress_vulnerable_packages(
-            all_vulnerable_packages, ignored_packages, ignored_codes
-        )
+        try:
+            # TODO: Pass auth key to build_client_session function for advanced safety usage.
+            session = build_safety_db_session(
+                proxy_protocol=self.option("proxy-protocol"),
+                proxy_host=self.option("proxy-host"),
+                proxy_port=int(self.option("proxy-port")) if self.option("proxy-port") else None,
+            )
+        except SafetyDBSessionBuildError as e:
+            self.chatty_line_error(f"<error>Error occured while building Safety DB session.</error>")
+            self.chatty_line_error("")
+            self.chatty_line_error(str(e))
+            sys.exit(e.get_exit_code())
+        try:
+            all_vulnerable_packages = check_vulnerable_packages(
+                session, packages, int(self.option("cache-sec")) if self.option("cache-sec") else 0
+            )
+        except SafetyDBAccessError as e:
+            self.chatty_line_error(f"<error>Error occured while accessing Safety DB.</error>")
+            self.chatty_line_error("")
+            self.chatty_line_error(str(e))
+            sys.exit(e.get_exit_code())
 
+        vulnerable_packages, amount_of_ignored_vulnerabilities = self.filter_vulnerable_packages(
+            all_vulnerable_packages,
+            ignored_packages,
+            ignored_codes,
+        )
         max_line_lengths = self.calculate_line_length(vulnerable_packages)
         amount_of_vulnerable_packages = len(vulnerable_packages)
         if self.option("json"):
             json_report = self.get_json_report(vulnerable_packages)
             self.chatty_line(json_report)
             if amount_of_vulnerable_packages > 0:
-                sys.exit(1)
+                sys.exit(EXIT_CODE_VULNERABILITY_FOUND)
+            else:
+                sys.exit(EXIT_CODE_OK)
         else:
             amount_of_vulnerabilities = 0
             for vulnerable_package in vulnerable_packages:
@@ -82,10 +155,10 @@ def handle(self) -> None:
                 self.line(
                     f"<error>{amount_of_vulnerabilities}</error> <b>vulnerabilities found in {amount_of_vulnerable_packages} packages</b>"
                 )
-                sys.exit(1)
+                sys.exit(EXIT_CODE_VULNERABILITY_FOUND)
             else:
-                self.line("<b>Vulnerabilities not found</b> ✨✨")
-                sys.exit(0)
+                self.line("<b>No vulnerabilities found</b> ✨✨")
+                sys.exit(EXIT_CODE_OK)
 
     def line(self, *args: Any, **kwargs: Any) -> None:
         if not self.is_quiet:
@@ -99,13 +172,34 @@ def chatty_line(self, *args: Any, **kwargs: Any) -> None:
         super().line(*args, **kwargs)
 
     def chatty_line_error(self, *args: Any, **kwargs: Any) -> None:
-        super().line(*args, **kwargs)
+        super().line_error(*args, **kwargs)
+
+    def validate_options(self) -> None:
+        errors: List[str] = []
+        if self.option("proxy-host") and (not self.option("proxy-protocol") or not self.option("proxy-port")):
+            errors.append("proxy-protocol and proxy-port should not be empty when proxy-host is specified.")
+
+        if self.option("proxy-protocol") and (self.option("proxy-protocol") not in ["http", "https"]):
+            errors.append("proxy-protocol should be http or https.")
+
+        if self.option("proxy-port") and not self.option("proxy-port").isnumeric():
+            errors.append("proxy-port should be number.")
+
+        if self.option("cache-sec") and not self.option("cache-sec").isnumeric():
+            errors.append("cache-sec be number")
+
+        if errors:
+            self.chatty_line_error("<error>Command line option(s) are invalid</error>")
+            for error in errors:
+                self.chatty_line_error(error)
+            sys.exit(EXIT_CODE_OPTION_INVALID)
 
     def validate_lock_file(self) -> None:
+        # Ref: https://github.com/python-poetry/poetry/blob/1.2.0b1/src/poetry/console/commands/export.py#L40
         locker = self.poetry.locker
         if not locker.is_locked():
             self.line_error("<comment>The lock file does not exist. Locking.</comment>")
-            option = "quiet" if self.is_quiet() else None
+            option = "quiet" if self.is_quiet else None
             self.call("lock", option)
             self.line("")
 
@@ -131,8 +225,7 @@ def calculate_line_length(self, vulnerable_packages: List[VulnerablePackage]) ->
                     else:
                         line_length = len(getattr(vulnerability, key))
 
-                    max_line_length = max_line_lengths[key]
-                    if line_length > max_line_length:
+                    if line_length > max_line_lengths[key]:
                         max_line_lengths[key] = line_length
 
         return max_line_lengths
@@ -152,6 +245,39 @@ def get_json_report(self, vulnerable_packages: List[VulnerablePackage]) -> str:
         }
         return json.dumps(json_report_dict, indent=2)
 
+    def filter_vulnerable_packages(
+        self, vulnerable_packages: List[VulnerablePackage], ignored_packages: List[str], ignored_codes: List[str]
+    ) -> Tuple[List[VulnerablePackage], int]:
+        filtered_vulnerable_packages: List[VulnerablePackage] = []
+        amount_of_ignored_vulnerabilities = 0
+
+        is_ignore_packages = len(ignored_packages) > 0
+        is_ignore_codes = len(ignored_codes) > 0
+
+        for vulnerable_package in vulnerable_packages:
+            filtered_vulnerable_package = copy.copy(vulnerable_package)
+            if is_ignore_packages:
+                if vulnerable_package.name in ignored_packages:
+                    amount_of_ignored_vulnerabilities += len(vulnerable_package.vulnerabilities)
+                    continue
+
+            if is_ignore_codes:
+                filtered_vulnerabilities: List[Vulnerability] = []
+                for vulnerability in vulnerable_package.vulnerabilities:
+                    if vulnerability.cve not in ignored_codes:
+                        filtered_vulnerabilities.append(vulnerability)
+                    else:
+                        amount_of_ignored_vulnerabilities += 1
+
+                if len(filtered_vulnerabilities):
+                    filtered_vulnerable_package.vulnerabilities = filtered_vulnerabilities
+                else:
+                    continue
+
+            filtered_vulnerable_packages.append(filtered_vulnerable_package)
+
+        return filtered_vulnerable_packages, amount_of_ignored_vulnerabilities
+
 
 def factory():
     return AuditCommand()
diff --git a/poetry_audit_plugin/constants.py b/poetry_audit_plugin/constants.py
new file mode 100644
index 0000000..3122292
--- /dev/null
+++ b/poetry_audit_plugin/constants.py
@@ -0,0 +1,5 @@
+EXIT_CODE_OK = 0
+EXIT_CODE_VULNERABILITY_FOUND = 1
+EXIT_CODE_OPTION_INVALID = 64
+EXIT_CODE_SAFETY_DB_SESSION_BUILD_ERROR = 65
+EXIT_CODE_SAFETY_DB_ACCESS_ERROR = 66
diff --git a/poetry_audit_plugin/errors.py b/poetry_audit_plugin/errors.py
new file mode 100644
index 0000000..75d0dbc
--- /dev/null
+++ b/poetry_audit_plugin/errors.py
@@ -0,0 +1,22 @@
+from poetry_audit_plugin.constants import (
+    EXIT_CODE_SAFETY_DB_ACCESS_ERROR,
+    EXIT_CODE_SAFETY_DB_SESSION_BUILD_ERROR,
+)
+
+
+class SafetyDBSessionBuildError(Exception):
+    def __init__(self, message) -> None:
+        self.message = message
+        super().__init__(self.message)
+
+    def get_exit_code(self) -> int:
+        return EXIT_CODE_SAFETY_DB_SESSION_BUILD_ERROR
+
+
+class SafetyDBAccessError(Exception):
+    def __init__(self, message) -> None:
+        self.message = message
+        super().__init__(self.message)
+
+    def get_exit_code(self) -> int:
+        return EXIT_CODE_SAFETY_DB_ACCESS_ERROR
diff --git a/poetry_audit_plugin/safety.py b/poetry_audit_plugin/safety.py
index 2e2bcc1..9361b6f 100644
--- a/poetry_audit_plugin/safety.py
+++ b/poetry_audit_plugin/safety.py
@@ -1,8 +1,11 @@
-from typing import Any, Dict, Iterator, List, Tuple
+from typing import Any, Dict, Iterator, List, Optional
 
 from packaging.specifiers import SpecifierSet
+from safety.auth import build_client_session
 from safety.safety import fetch_database
 
+from poetry_audit_plugin.errors import SafetyDBAccessError, SafetyDBSessionBuildError
+
 
 class Package:
     def __init__(self, name: str, version: str) -> None:
@@ -34,35 +37,69 @@ def format(self) -> Dict[str, Any]:
         }
 
 
-def get_vulnerable_entry(pkg_name: str, spec: str, db_full: Dict[str, Any]) -> Iterator[Dict[str, Any]]:
-    for entry in db_full.get(pkg_name, []):
+def build_safety_db_session(
+    key: Optional[str] = None,
+    proxy_protocol: Optional[str] = None,
+    proxy_host: Optional[str] = None,
+    proxy_port: Optional[int] = None,
+) -> Any:
+    # Ref: https://github.com/pyupio/safety/blob/3.0.1/safety/auth/cli_utils.py#L130
+    proxy_config: Optional[Dict[str, str]] = None
+    if proxy_host and proxy_port and proxy_protocol:
+        proxy_config = {"https": f"{proxy_protocol}://{proxy_host}:{str(proxy_port)}"}
+    try:
+        # Note: proxy_config is ignored when it's invalid or inaccessible inside build_client_session
+        session, _ = build_client_session(api_key=key, proxies=proxy_config)
+    except Exception as e:
+        raise SafetyDBSessionBuildError(str(e))
+
+    return session
+
+
+def get_vulnerable_entry(pkg_name: str, spec: str, db_full: Dict[str, Dict[str, Any]]) -> Iterator[Dict[str, Any]]:
+    for entry in db_full.get("vulnerable_packages", {}).get(pkg_name, []):
         for entry_spec in entry.get("specs", []):
             if entry_spec == spec:
                 yield entry
 
 
-def check_vulnerable_packages(packages: List[Package]) -> List[VulnerablePackage]:
-    db: Dict[str, Any] = fetch_database()
-    db_full: Dict[str, Any] = {}
+def check_vulnerable_packages(session: Any, packages: List[Package], cache_sec: int = 0) -> List[VulnerablePackage]:
+    """
+    Check vulnerabilities in given packages by checking Safety DB.
+
+    If cache_sec is not 0, Safety DB is cached in $HOME/.safety/200/ and it can be used for next scan.
+    """
+    # Ref: https://github.com/pyupio/safety/blob/2.3.5/safety/safety.py#L320
+    # Ref: https://github.com/pyupio/safety/blob/3.0.1/safety/scan/finder/handlers.py#L50
+    try:
+        db: Dict[str, Dict[str, Any]] = fetch_database(
+            session, full=False, db=False, cached=cache_sec, telemetry=False, from_cache=True
+        )
+        db_full: Dict[str, Dict[str, Any]] = fetch_database(
+            session, full=True, db=False, cached=cache_sec, telemetry=False, from_cache=True
+        )
+    except Exception as e:
+        raise SafetyDBAccessError(str(e))
+
     vulnerable_packages: List[VulnerablePackage] = []
     for pkg in packages:
         name = pkg.name.replace("_", "-").lower()
         vulnerabilities: List[Vulnerability] = []
-        if name in frozenset(db.keys()):
-            specifiers: List[str] = db[name]
-            for specifier in specifiers:
-                spec_set = SpecifierSet(specifiers=specifier)
-                if spec_set.contains(pkg.version):
-                    if not db_full:
-                        db_full = fetch_database(full=True)
-                    for data in get_vulnerable_entry(pkg_name=name, spec=specifier, db_full=db_full):
-                        cve = data.get("cve")
-                        if cve:
-                            cve = cve.split(",")[0].strip()
-                        if data.get("id"):
-                            vulnerabilities.append(
-                                Vulnerability(advisory=data.get("advisory", ""), cve=cve, spec=specifier)
-                            )
+        if name not in db.get("vulnerable_packages", {}).keys():
+            continue
+
+        specifiers: List[str] = db["vulnerable_packages"][name]
+        for specifier in specifiers:
+            spec_set = SpecifierSet(specifiers=specifier)
+            if not spec_set.contains(pkg.version):
+                continue
+
+            for entry in get_vulnerable_entry(pkg_name=name, spec=specifier, db_full=db_full):
+                for cve in entry.get("ids", []):
+                    if cve.get("type") in ["cve", "pve"] and cve.get("id"):
+                        vulnerabilities.append(
+                            Vulnerability(advisory=entry.get("advisory", ""), cve=cve["id"], spec=specifier)
+                        )
 
         if vulnerabilities:
             vulnerable_packages.append(
@@ -70,36 +107,3 @@ def check_vulnerable_packages(packages: List[Package]) -> List[VulnerablePackage
             )
 
     return vulnerable_packages
-
-
-def suppress_vulnerable_packages(
-    vulnerable_packages: List[VulnerablePackage], ignored_packages: List[str], ignored_codes: List[str]
-) -> Tuple[List[VulnerablePackage], int]:
-    filtered_vulnerable_packages: List[VulnerablePackage] = []
-    amount_of_ignored_vulnerabilities = 0
-
-    is_ignore_packages = len(ignored_packages) > 0
-    is_ignore_codes = len(ignored_codes) > 0
-
-    for vulnerable_package in vulnerable_packages:
-        if is_ignore_packages:
-            if vulnerable_package.name in ignored_packages:
-                amount_of_ignored_vulnerabilities += len(vulnerable_package.vulnerabilities)
-                continue
-
-        if is_ignore_codes:
-            filtered_vulnerabilities: List[Vulnerability] = []
-            for vulnerability in vulnerable_package.vulnerabilities:
-                if vulnerability.cve not in ignored_codes:
-                    filtered_vulnerabilities.append(vulnerability)
-                else:
-                    amount_of_ignored_vulnerabilities += 1
-
-            if len(filtered_vulnerabilities):
-                vulnerable_package.vulnerabilities = filtered_vulnerabilities
-            else:
-                continue
-
-        filtered_vulnerable_packages.append(vulnerable_package)
-
-    return filtered_vulnerable_packages, amount_of_ignored_vulnerabilities
diff --git a/pyproject.toml b/pyproject.toml
index e0f73b0..accb473 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,10 +21,10 @@ classifiers = [
     "Topic :: System :: Installation/Setup",
     "Topic :: System :: Software Distribution",
     "Programming Language :: Python :: 3 :: Only",
-    "Programming Language :: Python :: 3.7",
     "Programming Language :: Python :: 3.8",
     "Programming Language :: Python :: 3.9",
     "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
     "License :: OSI Approved :: MIT License"
 ]
 keywords = ["poetry", "vulnerabilities", "security", "audit"]
@@ -32,7 +32,7 @@ keywords = ["poetry", "vulnerabilities", "security", "audit"]
 [tool.poetry.dependencies]
 python = "^3.8"
 poetry = "^1.6.1"
-safety = "^2.3.5"
+safety = "^3.0.0"
 
 [tool.poetry.group.dev.dependencies]
 pytest = "^6.2.5"
diff --git a/tests/assets/no_vulnerabilities/poetry.lock b/tests/assets/no_vulnerabilities/poetry.lock
index c3585c5..2024428 100644
--- a/tests/assets/no_vulnerabilities/poetry.lock
+++ b/tests/assets/no_vulnerabilities/poetry.lock
@@ -1,643 +1,17 @@
-[[package]]
-name = "cachecontrol"
-version = "0.12.10"
-description = "httplib2 caching for requests"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""}
-msgpack = ">=0.5.2"
-requests = "*"
-
-[package.extras]
-filecache = ["lockfile (>=0.9)"]
-redis = ["redis (>=2.10.5)"]
-
-[[package]]
-name = "cachy"
-version = "0.3.0"
-description = "Cachy provides a simple yet effective caching library."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-redis = ["redis (>=3.3.6,<4.0.0)"]
-memcached = ["python-memcached (>=1.59,<2.0)"]
-msgpack = ["msgpack-python (>=0.5,<0.6)"]
-
-[[package]]
-name = "certifi"
-version = "2021.10.8"
-description = "Python package for providing Mozilla's CA Bundle."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "charset-normalizer"
-version = "2.0.12"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "main"
-optional = false
-python-versions = ">=3.5.0"
-
-[package.extras]
-unicode_backport = ["unicodedata2"]
-
-[[package]]
-name = "cleo"
-version = "1.0.0a4"
-description = "Cleo allows you to create beautiful and testable command-line interfaces."
-category = "main"
-optional = false
-python-versions = ">=3.6,<4.0"
-
-[package.dependencies]
-crashtest = ">=0.3.1,<0.4.0"
-pylev = ">=1.3.0,<2.0.0"
-
-[[package]]
-name = "crashtest"
-version = "0.3.1"
-description = "Manage Python errors with ease"
-category = "main"
-optional = false
-python-versions = ">=3.6,<4.0"
-
-[[package]]
-name = "cryptography"
-version = "36.0.2"
-description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "distlib"
-version = "0.3.4"
-description = "Distribution utilities"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "entrypoints"
-version = "0.3"
-description = "Discover and load entry points from installed packages."
-category = "main"
-optional = false
-python-versions = ">=2.7"
-
-[[package]]
-name = "filelock"
-version = "3.6.0"
-description = "A platform independent file lock."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"]
-testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"]
-
-[[package]]
-name = "html5lib"
-version = "1.1"
-description = "HTML parser based on the WHATWG HTML specification"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[package.dependencies]
-six = ">=1.9"
-webencodings = "*"
-
-[package.extras]
-all = ["genshi", "chardet (>=2.2)", "lxml"]
-chardet = ["chardet (>=2.2)"]
-genshi = ["genshi"]
-lxml = ["lxml"]
-
-[[package]]
-name = "idna"
-version = "3.3"
-description = "Internationalized Domain Names in Applications (IDNA)"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "importlib-metadata"
-version = "4.11.3"
-description = "Read metadata from Python packages"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-zipp = ">=0.5"
-
-[package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
-perf = ["ipython"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
-
-[[package]]
-name = "jeepney"
-version = "0.8.0"
-description = "Low-level, pure Python DBus protocol wrapper."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"]
-trio = ["trio", "async-generator"]
-
-[[package]]
-name = "keyring"
-version = "23.5.0"
-description = "Store and access your passwords safely."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-importlib-metadata = ">=3.6"
-jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""}
-pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""}
-SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""}
-
-[package.extras]
-docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"]
+# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand.
 
 [[package]]
-name = "lockfile"
-version = "0.12.2"
-description = "Platform-independent file locking module"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "msgpack"
-version = "1.0.3"
-description = "MessagePack (de)serializer."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "packaging"
-version = "20.9"
-description = "Core utilities for Python packages"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.dependencies]
-pyparsing = ">=2.0.2"
-
-[[package]]
-name = "pexpect"
-version = "4.8.0"
-description = "Pexpect allows easy control of interactive console applications."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-ptyprocess = ">=0.5"
-
-[[package]]
-name = "pkginfo"
-version = "1.8.2"
-description = "Query metadatdata from sdists / bdists / installed packages."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-testing = ["coverage", "nose"]
-
-[[package]]
-name = "platformdirs"
-version = "2.5.1"
-description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
-test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
-
-[[package]]
-name = "poetry"
-version = "1.2.0b1"
-description = "Python dependency management and packaging made easy."
-category = "main"
-optional = false
-python-versions = ">=3.7,<4.0"
-
-[package.dependencies]
-cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]}
-cachy = ">=0.3.0,<0.4.0"
-cleo = ">=1.0.0a4,<2.0.0"
-crashtest = ">=0.3.0,<0.4.0"
-entrypoints = ">=0.3,<0.4"
-html5lib = ">=1.0,<2.0"
-keyring = ">=21.2.0"
-packaging = ">=20.4,<21.0"
-pexpect = ">=4.7.0,<5.0.0"
-pkginfo = ">=1.5,<2.0"
-poetry-core = ">=1.1.0a7,<2.0.0"
-requests = ">=2.18,<3.0"
-requests-toolbelt = ">=0.9.1,<0.10.0"
-shellingham = ">=1.1,<2.0"
-tomlkit = ">=0.7.0,<1.0.0"
-urllib3 = ">=1.26.0,<2.0.0"
-virtualenv = "*"
-
-[[package]]
-name = "poetry-core"
-version = "1.1.0a7"
-description = "Poetry PEP 517 Build Backend"
-category = "main"
-optional = false
-python-versions = ">=3.7,<4.0"
-
-[[package]]
-name = "poetry-opeco17-test-plugin"
-version = "1.0.0"
+name = "opeco17-dummy-package"
+version = "0.1.0"
 description = ""
-category = "main"
-optional = false
-python-versions = ">=3.7,<4.0"
-
-[package.dependencies]
-poetry = ">=1.2.0b1dev0,<2.0.0"
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-description = "Run a subprocess in a pseudo terminal"
-category = "main"
 optional = false
-python-versions = "*"
-
-[[package]]
-name = "pylev"
-version = "1.4.0"
-description = "A pure Python Levenshtein implementation that's not freaking GPL'd."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pyparsing"
-version = "3.0.8"
-description = "pyparsing module - Classes and methods to define and execute parsing grammars"
-category = "main"
-optional = false
-python-versions = ">=3.6.8"
-
-[package.extras]
-diagrams = ["railroad-diagrams", "jinja2"]
-
-[[package]]
-name = "pywin32-ctypes"
-version = "0.2.0"
-description = ""
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "requests"
-version = "2.27.1"
-description = "Python HTTP for Humans."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
-idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
-urllib3 = ">=1.21.1,<1.27"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
-use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
-
-[[package]]
-name = "requests-toolbelt"
-version = "0.9.1"
-description = "A utility belt for advanced users of python-requests"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-requests = ">=2.0.1,<3.0.0"
-
-[[package]]
-name = "secretstorage"
-version = "3.3.1"
-description = "Python bindings to FreeDesktop.org Secret Service API"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-cryptography = ">=2.0"
-jeepney = ">=0.6"
-
-[[package]]
-name = "shellingham"
-version = "1.4.0"
-description = "Tool to Detect Surrounding Shell"
-category = "main"
-optional = false
-python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6"
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "tomlkit"
-version = "0.10.1"
-description = "Style preserving TOML library"
-category = "main"
-optional = false
-python-versions = ">=3.6,<4.0"
-
-[[package]]
-name = "urllib3"
-version = "1.26.9"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
-
-[package.extras]
-brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
-secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
-socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
-
-[[package]]
-name = "virtualenv"
-version = "20.14.1"
-description = "Virtual Python Environment builder"
-category = "main"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
-
-[package.dependencies]
-distlib = ">=0.3.1,<1"
-filelock = ">=3.2,<4"
-platformdirs = ">=2,<3"
-six = ">=1.9.0,<2"
-
-[package.extras]
-docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"]
-testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"]
-
-[[package]]
-name = "webencodings"
-version = "0.5.1"
-description = "Character encoding aliases for legacy web content"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "zipp"
-version = "3.8.0"
-description = "Backport of pathlib-compatible object wrapper for zip files"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
+python-versions = ">=3.10,<4.0"
+files = [
+    {file = "opeco17_dummy_package-0.1.0-py3-none-any.whl", hash = "sha256:57ba5f4732a2d308a4189bafd5a2a06f97ba8fcb2c92e1c17a2ed5452a39ae75"},
+    {file = "opeco17_dummy_package-0.1.0.tar.gz", hash = "sha256:db558a510f52c651b502e3e576fc7f712e753ea35c80599c01469db7df17661c"},
+]
 
 [metadata]
-lock-version = "1.1"
-python-versions = "^3.9"
-content-hash = "2ff55d310a7b1d66a7ecd23f0bc85076a6479091cf3bcdabe9e152331e0f0082"
-
-[metadata.files]
-cachecontrol = [
-    {file = "CacheControl-0.12.10-py2.py3-none-any.whl", hash = "sha256:b0d43d8f71948ef5ebdee5fe236b86c6ffc7799370453dccb0e894c20dfa487c"},
-    {file = "CacheControl-0.12.10.tar.gz", hash = "sha256:d8aca75b82eec92d84b5d6eb8c8f66ea16f09d2adb09dbca27fe2d5fc8d3732d"},
-]
-cachy = [
-    {file = "cachy-0.3.0-py2.py3-none-any.whl", hash = "sha256:338ca09c8860e76b275aff52374330efedc4d5a5e45dc1c5b539c1ead0786fe7"},
-    {file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"},
-]
-certifi = [
-    {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
-    {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
-]
-charset-normalizer = [
-    {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
-    {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
-]
-cleo = [
-    {file = "cleo-1.0.0a4-py3-none-any.whl", hash = "sha256:cdd0c3458c15ced3a9f0204b1e53a1b4bee3c56ebcb3ac54c872a56acc657a09"},
-    {file = "cleo-1.0.0a4.tar.gz", hash = "sha256:a103a065d031b7d936ee88a6b93086a69bd9c1b40fa2ebfe8c056285a66b481d"},
-]
-crashtest = [
-    {file = "crashtest-0.3.1-py3-none-any.whl", hash = "sha256:300f4b0825f57688b47b6d70c6a31de33512eb2fa1ac614f780939aa0cf91680"},
-    {file = "crashtest-0.3.1.tar.gz", hash = "sha256:42ca7b6ce88b6c7433e2ce47ea884e91ec93104a4b754998be498a8e6c3d37dd"},
-]
-cryptography = [
-    {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6"},
-    {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d"},
-    {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84"},
-    {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815"},
-    {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf"},
-    {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf"},
-    {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86"},
-    {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2"},
-    {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb"},
-    {file = "cryptography-36.0.2-cp36-abi3-win32.whl", hash = "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6"},
-    {file = "cryptography-36.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29"},
-    {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7"},
-    {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e"},
-    {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0"},
-    {file = "cryptography-36.0.2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b"},
-    {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77"},
-    {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85"},
-    {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51"},
-    {file = "cryptography-36.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3"},
-    {file = "cryptography-36.0.2.tar.gz", hash = "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9"},
-]
-distlib = [
-    {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
-    {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"},
-]
-entrypoints = [
-    {file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"},
-    {file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"},
-]
-filelock = [
-    {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"},
-    {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"},
-]
-html5lib = [
-    {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
-    {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
-]
-idna = [
-    {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
-    {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
-]
-importlib-metadata = [
-    {file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"},
-    {file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"},
-]
-jeepney = [
-    {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"},
-    {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"},
-]
-keyring = [
-    {file = "keyring-23.5.0-py3-none-any.whl", hash = "sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261"},
-    {file = "keyring-23.5.0.tar.gz", hash = "sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9"},
-]
-lockfile = [
-    {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"},
-    {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"},
-]
-msgpack = [
-    {file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079"},
-    {file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3"},
-    {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73"},
-    {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147"},
-    {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39"},
-    {file = "msgpack-1.0.3-cp310-cp310-win32.whl", hash = "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85"},
-    {file = "msgpack-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7"},
-    {file = "msgpack-1.0.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d"},
-    {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b"},
-    {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec"},
-    {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770"},
-    {file = "msgpack-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9"},
-    {file = "msgpack-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a"},
-    {file = "msgpack-1.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a"},
-    {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc"},
-    {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a"},
-    {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920"},
-    {file = "msgpack-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50"},
-    {file = "msgpack-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba"},
-    {file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea"},
-    {file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a"},
-    {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef"},
-    {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611"},
-    {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1"},
-    {file = "msgpack-1.0.3-cp38-cp38-win32.whl", hash = "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4"},
-    {file = "msgpack-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a"},
-    {file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3"},
-    {file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52"},
-    {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2"},
-    {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996"},
-    {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2"},
-    {file = "msgpack-1.0.3-cp39-cp39-win32.whl", hash = "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88"},
-    {file = "msgpack-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d"},
-    {file = "msgpack-1.0.3.tar.gz", hash = "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e"},
-]
-packaging = [
-    {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"},
-    {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"},
-]
-pexpect = [
-    {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
-    {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
-]
-pkginfo = [
-    {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"},
-    {file = "pkginfo-1.8.2.tar.gz", hash = "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff"},
-]
-platformdirs = [
-    {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"},
-    {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"},
-]
-poetry = [
-    {file = "poetry-1.2.0b1-py3-none-any.whl", hash = "sha256:e3d68c88492550c48df10c738e962f1f770ad71e715bab878a46f527e1ce81d2"},
-    {file = "poetry-1.2.0b1.tar.gz", hash = "sha256:26cf8d309a74fff25d768219c2215a989a530acab886c01de3db07ab70bc7abf"},
-]
-poetry-core = [
-    {file = "poetry-core-1.1.0a7.tar.gz", hash = "sha256:4622ae680842ac9b1b9c3b0e8dc467c2e291d1a5c434b6bd413907a2e5571d92"},
-    {file = "poetry_core-1.1.0a7-py3-none-any.whl", hash = "sha256:724e8b5368f270461e622396305d0c2e760ec9d4c14d072e6b944da9384c67de"},
-]
-poetry-opeco17-test-plugin = [
-    {file = "poetry-opeco17-test-plugin-1.0.0.tar.gz", hash = "sha256:5b734dc66ecbbf7cb1fb6b068e99c20e83f83e4b48ef723b6e0cbd92430b3500"},
-    {file = "poetry_opeco17_test_plugin-1.0.0-py3-none-any.whl", hash = "sha256:15cd6780040b6eeabc5310bc4bcdd6af2317fe81e42dcc9f3694742e9ce0bc89"},
-]
-ptyprocess = [
-    {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
-    {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-pylev = [
-    {file = "pylev-1.4.0-py2.py3-none-any.whl", hash = "sha256:7b2e2aa7b00e05bb3f7650eb506fc89f474f70493271a35c242d9a92188ad3dd"},
-    {file = "pylev-1.4.0.tar.gz", hash = "sha256:9e77e941042ad3a4cc305dcdf2b2dec1aec2fbe3dd9015d2698ad02b173006d1"},
-]
-pyparsing = [
-    {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"},
-    {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"},
-]
-pywin32-ctypes = [
-    {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
-    {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"},
-]
-requests = [
-    {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
-    {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
-]
-requests-toolbelt = [
-    {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
-    {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
-]
-secretstorage = [
-    {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"},
-    {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"},
-]
-shellingham = [
-    {file = "shellingham-1.4.0-py2.py3-none-any.whl", hash = "sha256:536b67a0697f2e4af32ab176c00a50ac2899c5a05e0d8e2dadac8e58888283f9"},
-    {file = "shellingham-1.4.0.tar.gz", hash = "sha256:4855c2458d6904829bd34c299f11fdeed7cfefbf8a2c522e4caea6cd76b3171e"},
-]
-six = [
-    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
-    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-tomlkit = [
-    {file = "tomlkit-0.10.1-py3-none-any.whl", hash = "sha256:3eba517439dcb2f84cf39f4f85fd2c3398309823a3c75ac3e73003638daf7915"},
-    {file = "tomlkit-0.10.1.tar.gz", hash = "sha256:3c517894eadef53e9072d343d37e4427b8f0b6200a70b7c9a19b2ebd1f53b951"},
-]
-urllib3 = [
-    {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
-    {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
-]
-virtualenv = [
-    {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"},
-    {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"},
-]
-webencodings = [
-    {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
-    {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
-]
-zipp = [
-    {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
-    {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
-]
+lock-version = "2.0"
+python-versions = "^3.10"
+content-hash = "ff9fc901b270620b6ca62d914aeaef60996163f92b8e0b263d685af8f0d9b2a1"
diff --git a/tests/assets/no_vulnerabilities/pyproject.toml b/tests/assets/no_vulnerabilities/pyproject.toml
index a9c2976..6f92f03 100644
--- a/tests/assets/no_vulnerabilities/pyproject.toml
+++ b/tests/assets/no_vulnerabilities/pyproject.toml
@@ -1,14 +1,14 @@
 [tool.poetry]
-name = "no-vulnerabilities"
+name = "poetry-audit-demo"
 version = "0.1.0"
 description = ""
 authors = ["opeco17 <opeco17@gmail.com>"]
 readme = "README.md"
-packages = [{include = "no_vulnerabilities"}]
 
 [tool.poetry.dependencies]
-python = "^3.9"
-poetry-opeco17-test-plugin = "^1.0.0"
+python = "^3.10"
+opeco17-dummy-package = "^0.1.0"
+
 
 [build-system]
 requires = ["poetry-core"]
diff --git a/tests/test_main.py b/tests/test_main.py
index a0764cc..afb948a 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -5,9 +5,12 @@
 from subprocess import CompletedProcess
 from typing import List
 
+from poetry_audit_plugin.constants import *
+
 # At least there're following vulnerabilities in these packages.
 DEV_VULNERABILITY_PACKAGE = "ansible-runner"
 DEV_VULNERABILITY_CODE1 = "PVE-2021-36995"
+DEV_VULNERABILITY_CODE2 = "CVE-2021-4041"
 MAIN_VULNERABILITY_PACKAGE = "ansible-tower-cli"
 MAIN_VULNERABILITY_CODE1 = "CVE-2020-1735"
 MAIN_VULNERABILITY_CODE2 = "CVE-2020-1738"
@@ -20,13 +23,15 @@ def copy_assets(source_name: str, testing_dir: Path) -> None:
     shutil.copytree(package_path, testing_dir)
 
 
-def run_audit(testing_dir: Path, args: List[str] = []) -> CompletedProcess:
+def run_audit(testing_dir: Path, use_cache: bool, *args: str) -> CompletedProcess:
+    commands = [
+        "poetry",
+        "audit",
+    ] + list(args)
+    if use_cache:
+        commands.append("--cache-sec=60")
     result = subprocess.run(
-        [
-            "poetry",
-            "audit",
-        ]
-        + args,
+        commands,
         cwd=testing_dir,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
@@ -38,164 +43,169 @@ def run_audit(testing_dir: Path, args: List[str] = []) -> CompletedProcess:
 def test_no_vulnerabilities_basic_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("no_vulnerabilities", testing_dir)
-    result = run_audit(testing_dir=testing_dir)
+    result = run_audit(testing_dir, True)
 
     assert "poetry audit report" in result.stdout
-    assert "Vulnerabilities not found" in result.stdout
-    assert result.returncode == 0
+    assert "No vulnerabilities found" in result.stdout
+    assert result.returncode == EXIT_CODE_OK
 
 
 def test_vulnerabilities_in_main_basic_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main", testing_dir)
-    result = run_audit(testing_dir=testing_dir)
+    result = run_audit(testing_dir, True)
 
     assert "poetry audit report" in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE in result.stdout
     assert MAIN_VULNERABILITY_CODE1 in result.stdout
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
     assert "vulnerabilities found" in result.stdout
-    assert result.returncode == 1
+    assert "No vulnerabilities found" not in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_dev_basic_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir)
+    result = run_audit(testing_dir, True)
 
     assert "poetry audit report" in result.stdout
     assert DEV_VULNERABILITY_PACKAGE in result.stdout
     assert DEV_VULNERABILITY_CODE1 in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
     assert "vulnerabilities found" in result.stdout
-    assert result.returncode == 1
+    assert "No vulnerabilities found" not in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_main_dev_basic_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir)
+    result = run_audit(testing_dir, True)
 
     assert "poetry audit report" in result.stdout
     assert DEV_VULNERABILITY_PACKAGE in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE in result.stdout
     assert DEV_VULNERABILITY_CODE1 in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
     assert MAIN_VULNERABILITY_CODE1 in result.stdout
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
     assert "vulnerabilities found" in result.stdout
-    assert result.returncode == 1
+    assert "No vulnerabilities found" not in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_no_vulnerabilities_json_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("no_vulnerabilities", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json"])
+    result = run_audit(testing_dir, True, "--json")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = [vulnerability["name"] for vulnerability in result_dict["vulnerabilities"]]
 
+    assert "poetry audit report" not in result.stdout
+    assert "metadata" in result_dict.keys()
     assert len(vulnerabilitie_names) == 0
-    assert result.returncode == 0
+    assert result.returncode == EXIT_CODE_OK
 
 
 def test_vulnerabilities_in_main_json_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json"])
+    result = run_audit(testing_dir, True, "--json")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = [vulnerability["name"] for vulnerability in result_dict["vulnerabilities"]]
 
+    assert "poetry audit report" not in result.stdout
+    assert "metadata" in result_dict.keys()
     assert MAIN_VULNERABILITY_PACKAGE in vulnerabilitie_names
     assert MAIN_VULNERABILITY_CODE1 in result.stdout
-    assert result.returncode == 1
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_dev_json_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json"])
+    result = run_audit(testing_dir, True, "--json")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = [vulnerability["name"] for vulnerability in result_dict["vulnerabilities"]]
 
+    assert "poetry audit report" not in result.stdout
+    assert "metadata" in result_dict.keys()
     assert DEV_VULNERABILITY_PACKAGE in vulnerabilitie_names
     assert DEV_VULNERABILITY_CODE1 in result.stdout
-    assert result.returncode == 1
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_main_dev_json_report(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json"])
+    result = run_audit(testing_dir, True, "--json")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = [vulnerability["name"] for vulnerability in result_dict["vulnerabilities"]]
 
+    assert "poetry audit report" not in result.stdout
+    assert "metadata" in result_dict.keys()
     assert DEV_VULNERABILITY_PACKAGE in vulnerabilitie_names
     assert MAIN_VULNERABILITY_PACKAGE in vulnerabilitie_names
     assert DEV_VULNERABILITY_CODE1 in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
     assert MAIN_VULNERABILITY_CODE1 in result.stdout
-    assert result.returncode == 1
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_code_in_main_basic_report_with_ignoring_codes(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main", testing_dir)
-    result = run_audit(
-        testing_dir=testing_dir, args=[f"--ignore-code={MAIN_VULNERABILITY_CODE1},{MAIN_VULNERABILITY_CODE2}"]
-    )
+    result = run_audit(testing_dir, True, f"--ignore-code={MAIN_VULNERABILITY_CODE1}")
 
     assert "poetry audit report" in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE in result.stdout
     assert "vulnerabilities found in" in result.stdout
     assert "vulnerabilities found but ignored" in result.stdout
     assert MAIN_VULNERABILITY_CODE1 not in result.stdout
-    assert MAIN_VULNERABILITY_CODE2 not in result.stdout
-    assert result.returncode == 1
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_main_dev_basic_report_with_ignoring_codes(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main_dev", testing_dir)
-    result = run_audit(
-        testing_dir=testing_dir, args=[f"--ignore-code={MAIN_VULNERABILITY_CODE1},{MAIN_VULNERABILITY_CODE2}"]
-    )
+    result = run_audit(testing_dir, True, f"--ignore-code={MAIN_VULNERABILITY_CODE1},{DEV_VULNERABILITY_CODE1}")
 
     assert "poetry audit report" in result.stdout
     assert DEV_VULNERABILITY_PACKAGE in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE in result.stdout
     assert MAIN_VULNERABILITY_CODE1 not in result.stdout
-    assert MAIN_VULNERABILITY_CODE2 not in result.stdout
+    assert MAIN_VULNERABILITY_CODE2 in result.stdout
+    assert DEV_VULNERABILITY_CODE1 not in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
     assert "vulnerabilities found in" in result.stdout
     assert "vulnerabilities found but ignored" in result.stdout
-    assert result.returncode == 1
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_dev_basic_report_with_ignoring_codes(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_dev", testing_dir)
-    result = run_audit(
-        testing_dir=testing_dir, args=["--ignore-code={MAIN_VULNERABILITY_CODE1},{MAIN_VULNERABILITY_CODE2}"]
-    )
+    result = run_audit(testing_dir, True, f"--ignore-code={DEV_VULNERABILITY_CODE1}")
 
     assert "poetry audit report" in result.stdout
     assert DEV_VULNERABILITY_PACKAGE in result.stdout
+    assert DEV_VULNERABILITY_CODE1 not in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
     assert "vulnerabilities found in" in result.stdout
     assert "vulnerabilities found but ignored" in result.stdout
-    assert result.returncode == 1
-
-
-def test_vulnerabilities_in_main_dev_basic_report_with_ignoring_packages(tmp_path: Path) -> None:
-    testing_dir = tmp_path / "testing_package"
-    copy_assets("vulnerabilities_in_main_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=[f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}"])
-
-    assert "poetry audit report" in result.stdout
-    assert "vulnerabilities found but ignored" in result.stdout
-    assert DEV_VULNERABILITY_PACKAGE in result.stdout
-    assert MAIN_VULNERABILITY_PACKAGE not in result.stdout
-    assert result.returncode == 1
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
 def test_vulnerabilities_in_main_dev_json_report_with_ignoring_codes(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main_dev", testing_dir)
     result = run_audit(
-        testing_dir=testing_dir, args=["--json", f"--ignore-code={MAIN_VULNERABILITY_CODE1},{MAIN_VULNERABILITY_CODE2}"]
+        testing_dir, True, "--json", f"--ignore-code={MAIN_VULNERABILITY_CODE1},{DEV_VULNERABILITY_CODE1}"
     )
     result_dict = json.loads(result.stdout)
     vulnerability_names: List[str] = []
@@ -205,46 +215,165 @@ def test_vulnerabilities_in_main_dev_json_report_with_ignoring_codes(tmp_path: P
         for detail in vuln["vulns"]:
             vulnerability_codes.append(detail["cve"])
 
-    assert DEV_VULNERABILITY_PACKAGE in vulnerability_names
+    assert "poetry audit report" not in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE in vulnerability_names
+    assert DEV_VULNERABILITY_PACKAGE in vulnerability_names
     assert MAIN_VULNERABILITY_CODE1 not in vulnerability_codes
-    assert MAIN_VULNERABILITY_CODE2 not in vulnerability_codes
-    assert result.returncode == 1
+    assert MAIN_VULNERABILITY_CODE2 in vulnerability_codes
+    assert DEV_VULNERABILITY_CODE1 not in result.stdout
+    assert DEV_VULNERABILITY_CODE2 in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
-def test_no_vulnerabilities_in_main_basic_report_with_ignoring_packages(tmp_path: Path) -> None:
+def test_vulnerabilities_in_main_dev_basic_report_with_ignoring_main_packages(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
-    copy_assets("vulnerabilities_in_main", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=[f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}"])
+    copy_assets("vulnerabilities_in_main_dev", testing_dir)
+    result = run_audit(testing_dir, True, f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}")
 
     assert "poetry audit report" in result.stdout
     assert "vulnerabilities found but ignored" in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE not in result.stdout
-    assert result.returncode == 0
+    assert DEV_VULNERABILITY_PACKAGE in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
+
+
+def test_vulnerabilities_in_main_dev_basic_report_with_ignoring_dev_packages(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("vulnerabilities_in_main_dev", testing_dir)
+    result = run_audit(testing_dir, True, f"--ignore-package={DEV_VULNERABILITY_PACKAGE}")
+
+    assert "poetry audit report" in result.stdout
+    assert "vulnerabilities found but ignored" in result.stdout
+    assert MAIN_VULNERABILITY_PACKAGE in result.stdout
+    assert DEV_VULNERABILITY_PACKAGE not in result.stdout
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
-def test_vulnerabilities_in_main_dev_json_report_with_ignoring_packages(tmp_path: Path) -> None:
+def test_vulnerabilities_in_main_dev_json_report_with_ignoring_main_packages(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
     copy_assets("vulnerabilities_in_main_dev", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json", f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}"])
+    result = run_audit(testing_dir, True, "--json", f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = []
     for vuln in result_dict["vulnerabilities"]:
         vulnerabilitie_names.append(vuln["name"])
 
-    assert DEV_VULNERABILITY_PACKAGE in vulnerabilitie_names
+    assert "poetry audit report" not in result.stdout
     assert MAIN_VULNERABILITY_PACKAGE not in vulnerabilitie_names
-    assert result.returncode == 1
+    assert DEV_VULNERABILITY_PACKAGE in vulnerabilitie_names
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
 
 
-def test_no_vulnerabilities_in_main_json_report_with_ignoring_packages(tmp_path: Path) -> None:
+def test_vulnerabilities_in_main_dev_json_report_with_ignoring_dev_packages(tmp_path: Path) -> None:
     testing_dir = tmp_path / "testing_package"
-    copy_assets("vulnerabilities_in_main", testing_dir)
-    result = run_audit(testing_dir=testing_dir, args=["--json", f"--ignore-package={MAIN_VULNERABILITY_PACKAGE}"])
+    copy_assets("vulnerabilities_in_main_dev", testing_dir)
+    result = run_audit(testing_dir, True, "--json", f"--ignore-package={DEV_VULNERABILITY_PACKAGE}")
     result_dict = json.loads(result.stdout)
     vulnerabilitie_names = []
     for vuln in result_dict["vulnerabilities"]:
         vulnerabilitie_names.append(vuln["name"])
 
-    assert MAIN_VULNERABILITY_PACKAGE not in vulnerabilitie_names
-    assert result.returncode == 0
+    assert "poetry audit report" not in result.stdout
+    assert MAIN_VULNERABILITY_PACKAGE in vulnerabilitie_names
+    assert DEV_VULNERABILITY_PACKAGE not in vulnerabilitie_names
+    assert result.returncode == EXIT_CODE_VULNERABILITY_FOUND
+
+
+def test_no_vulnerabilities_basic_report_with_valid_proxy_config(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, False, "--proxy-protocol=http", "--proxy-host=localhost", "--proxy-port=3128")
+
+    assert "poetry audit report" in result.stdout
+    assert result.returncode == EXIT_CODE_OK
+
+
+def test_no_vulnerabilities_basic_report_with_invalid_string_proxy_port(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--proxy-host=localhost", "--proxy-port=string")
+
+    assert "poetry audit report" in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_basic_report_with_invalid_empty_proxy_port(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--proxy-host=localhost", "--proxy-port=''")
+
+    assert "poetry audit report" in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_basic_report_with_invalid_string_proxy_protocol(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--proxy-host=localhost", "--proxy-protocol='tcp'")
+
+    assert "poetry audit report" in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_basic_report_with_invalid_empty_proxy_protocol(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--proxy-host=localhost", "--proxy-protocol=''")
+
+    assert "poetry audit report" in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_json_report_with_valid_proxy_config(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(
+        testing_dir, False, "--json", "--proxy-protocol=http", "--proxy-host=localhost", "--proxy-port=3128"
+    )
+
+    assert "poetry audit report" not in result.stdout
+    assert result.returncode == EXIT_CODE_OK
+
+
+def test_no_vulnerabilities_json_report_with_invalid_string_proxy_port(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--json", "--proxy-host=localhost", "--proxy-port=string")
+
+    assert "poetry audit report" not in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_json_report_with_invalid_empty_proxy_port(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--json", "--proxy-host=localhost", "--proxy-port=''")
+
+    assert "poetry audit report" not in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_json_report_with_invalid_string_proxy_protocol(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--json", "--proxy-host=localhost", "--proxy-protocol='tcp'")
+
+    assert "poetry audit report" not in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID
+
+
+def test_no_vulnerabilities_json_report_with_invalid_empty_proxy_protocol(tmp_path: Path) -> None:
+    testing_dir = tmp_path / "testing_package"
+    copy_assets("no_vulnerabilities", testing_dir)
+    result = run_audit(testing_dir, True, "--json", "--proxy-host=localhost", "--proxy-protocol=''")
+
+    assert "poetry audit report" not in result.stdout
+    assert "Command line option(s) are invalid" in result.stderr
+    assert result.returncode == EXIT_CODE_OPTION_INVALID