Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-certbot-dns-route53 for 
openSUSE:Factory checked in at 2023-06-07 23:08:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-certbot-dns-route53 (Old)
 and      /work/SRC/openSUSE:Factory/.python-certbot-dns-route53.new.15902 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-certbot-dns-route53"

Wed Jun  7 23:08:12 2023 rev:38 rq:1091315 version:2.6.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-certbot-dns-route53/python-certbot-dns-route53.changes
    2022-10-27 13:55:21.812932083 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-certbot-dns-route53.new.15902/python-certbot-dns-route53.changes
 2023-06-07 23:08:51.055841196 +0200
@@ -1,0 +2,13 @@
+Wed Jun  7 16:06:01 UTC 2023 - Markéta Machová <[email protected]>
+
+- update to version 2.6.0
+  * Support for Python 3.11 was added to Certbot and all of its components.
+  * All Certbot components now require pytest to run tests.
+  * Packaged tests for all Certbot components besides josepy were moved inside 
the _internal/tests module.
+  * There is now a new Other annotated challenge object to allow plugins to 
support entirely novel challenges.
+  * --dns-route53-propagation-seconds is now deprecated. The Route53 plugin 
relies on the GetChange API to 
+    determine if a DNS update is complete. The flag has never had any effect 
and will be removed in a future 
+    version of Certbot.
+  * Certbot no longer depends on zope.
+
+-------------------------------------------------------------------

Old:
----
  certbot-dns-route53-1.31.0.tar.gz

New:
----
  certbot-dns-route53-2.6.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-certbot-dns-route53.spec ++++++
--- /var/tmp/diff_new_pack.D9FpVC/_old  2023-06-07 23:08:51.871845935 +0200
+++ /var/tmp/diff_new_pack.D9FpVC/_new  2023-06-07 23:08:51.875845958 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-certbot-dns-route53
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python3-%{**}}
 %define skip_python2 1
 Name:           python-certbot-dns-route53
-Version:        1.31.0
+Version:        2.6.0
 Release:        0
 Summary:        Route53 DNS Authenticator plugin for Certbot
 License:        Apache-2.0
@@ -30,13 +30,11 @@
 BuildRequires:  %{python_module certbot >= %{version}}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools}
-BuildRequires:  %{python_module zope.interface}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       python-acme >= %{version}
 Requires:       python-boto3 >= 1.15.15
 Requires:       python-certbot >= %{version}
-Requires:       python-zope.interface
 BuildArch:      noarch
 %python_subpackages
 

++++++ certbot-dns-route53-1.31.0.tar.gz -> certbot-dns-route53-2.6.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-dns-route53-1.31.0/MANIFEST.in 
new/certbot-dns-route53-2.6.0/MANIFEST.in
--- old/certbot-dns-route53-1.31.0/MANIFEST.in  2022-10-04 16:40:41.000000000 
+0200
+++ new/certbot-dns-route53-2.6.0/MANIFEST.in   2023-05-09 21:44:36.000000000 
+0200
@@ -1,7 +1,6 @@
 include LICENSE.txt
 include README.rst
 recursive-include docs *
-recursive-include tests *
 include certbot_dns_route53/py.typed
 global-exclude __pycache__
 global-exclude *.py[cod]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-dns-route53-1.31.0/PKG-INFO 
new/certbot-dns-route53-2.6.0/PKG-INFO
--- old/certbot-dns-route53-1.31.0/PKG-INFO     2022-10-04 16:41:17.562428200 
+0200
+++ new/certbot-dns-route53-2.6.0/PKG-INFO      2023-05-09 21:45:01.334482200 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: certbot-dns-route53
-Version: 1.31.0
+Version: 2.6.0
 Summary: Route53 DNS Authenticator plugin for Certbot
 Home-page: https://github.com/certbot/certbot
 Author: Certbot Project
@@ -18,6 +18,7 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Security
 Classifier: Topic :: System :: Installation/Setup
@@ -26,4 +27,5 @@
 Classifier: Topic :: Utilities
 Requires-Python: >=3.7
 Provides-Extra: docs
+Provides-Extra: test
 License-File: LICENSE.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/__init__.py 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/__init__.py
--- old/certbot-dns-route53-1.31.0/certbot_dns_route53/__init__.py      
2022-10-04 16:40:41.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/certbot_dns_route53/__init__.py       
2023-05-09 21:44:36.000000000 +0200
@@ -8,17 +8,6 @@
    `certbot.eff.org <https://certbot.eff.org/instructions#wildcard>`_, 
choosing your system and
    selecting the Wildcard tab.
 
-Named Arguments
----------------
-
-========================================  =====================================
-``--dns-route53-propagation-seconds``     The number of seconds to wait for DNS
-                                          to propagate before asking the ACME
-                                          server to verify the DNS record.
-                                          (Default: 10)
-========================================  =====================================
-
-
 Credentials
 -----------
 Use of this plugin requires a configuration file containing Amazon Web Sevices
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/dns_route53.py 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/dns_route53.py
--- old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/dns_route53.py 
2022-10-04 16:40:41.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/dns_route53.py  
2023-05-09 21:44:36.000000000 +0200
@@ -3,6 +3,7 @@
 import logging
 import time
 from typing import Any
+from typing import Callable
 from typing import DefaultDict
 from typing import Dict
 from typing import List
@@ -12,9 +13,11 @@
 from botocore.exceptions import NoCredentialsError
 
 from acme.challenges import ChallengeResponse
+from certbot import achallenges
 from certbot import errors
 from certbot.achallenges import AnnotatedChallenge
 from certbot.plugins import dns_common
+from certbot.util import add_deprecated_argument
 
 logger = logging.getLogger(__name__)
 
@@ -44,6 +47,17 @@
     def more_info(self) -> str:
         return "Solve a DNS01 challenge using AWS Route53"
 
+    @classmethod
+    def add_parser_arguments(cls, add: Callable[..., None],  # pylint: 
disable=arguments-differ
+                             default_propagation_seconds: int = 10) -> None:
+        add_deprecated_argument(add, 'propagation-seconds', 1)
+
+    def auth_hint(self, failed_achalls: List[achallenges.AnnotatedChallenge]) 
-> str:
+        return (
+            'The Certificate Authority failed to verify the DNS TXT records 
created by '
+            '--dns-route53. Ensure the above domains have their DNS hosted by 
AWS Route53.'
+        )
+
     def _setup_credentials(self) -> None:
         pass
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/tests/__init__.py 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/tests/__init__.py
--- 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/tests/__init__.py  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/tests/__init__.py   
    2023-05-09 21:44:36.000000000 +0200
@@ -0,0 +1 @@
+"""certbot-dns-route53 tests"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/tests/dns_route53_test.py
 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/tests/dns_route53_test.py
--- 
old/certbot-dns-route53-1.31.0/certbot_dns_route53/_internal/tests/dns_route53_test.py
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/certbot-dns-route53-2.6.0/certbot_dns_route53/_internal/tests/dns_route53_test.py
       2023-05-09 21:44:36.000000000 +0200
@@ -0,0 +1,263 @@
+"""Tests for certbot_dns_route53._internal.dns_route53.Authenticator"""
+
+import sys
+import unittest
+from unittest import mock
+
+from botocore.exceptions import ClientError
+from botocore.exceptions import NoCredentialsError
+import pytest
+
+from certbot import errors
+from certbot.compat import os
+from certbot.plugins import dns_test_common
+from certbot.plugins.dns_test_common import DOMAIN
+
+
+class AuthenticatorTest(unittest.TestCase, 
dns_test_common.BaseAuthenticatorTest):
+    # pylint: disable=protected-access
+
+    def setUp(self):
+        from certbot_dns_route53._internal.dns_route53 import Authenticator
+
+        super().setUp()
+
+        self.config = mock.MagicMock()
+
+        # Set up dummy credentials for testing
+        os.environ["AWS_ACCESS_KEY_ID"] = "dummy_access_key"
+        os.environ["AWS_SECRET_ACCESS_KEY"] = "dummy_secret_access_key"
+
+        self.auth = Authenticator(self.config, "route53")
+
+    def tearDown(self):
+        # Remove the dummy credentials from env vars
+        del os.environ["AWS_ACCESS_KEY_ID"]
+        del os.environ["AWS_SECRET_ACCESS_KEY"]
+
+    def test_perform(self):
+        self.auth._change_txt_record = mock.MagicMock()
+        self.auth._wait_for_change = mock.MagicMock()
+
+        self.auth.perform([self.achall])
+
+        self.auth._change_txt_record.assert_called_once_with("UPSERT",
+                                                             
'_acme-challenge.' + DOMAIN,
+                                                             mock.ANY)
+        assert self.auth._wait_for_change.call_count == 1
+
+    def test_perform_no_credentials_error(self):
+        self.auth._change_txt_record = 
mock.MagicMock(side_effect=NoCredentialsError)
+
+        with pytest.raises(errors.PluginError):
+            self.auth.perform([self.achall])
+
+    def test_perform_client_error(self):
+        self.auth._change_txt_record = mock.MagicMock(
+            side_effect=ClientError({"Error": {"Code": "foo"}}, "bar"))
+
+        with pytest.raises(errors.PluginError):
+            self.auth.perform([self.achall])
+
+    def test_cleanup(self):
+        self.auth._attempt_cleanup = True
+
+        self.auth._change_txt_record = mock.MagicMock()
+
+        self.auth.cleanup([self.achall])
+
+        self.auth._change_txt_record.assert_called_once_with("DELETE",
+                                                             
'_acme-challenge.'+DOMAIN,
+                                                             mock.ANY)
+
+    def test_cleanup_no_credentials_error(self):
+        self.auth._attempt_cleanup = True
+
+        self.auth._change_txt_record = 
mock.MagicMock(side_effect=NoCredentialsError)
+
+        self.auth.cleanup([self.achall])
+
+    def test_cleanup_client_error(self):
+        self.auth._attempt_cleanup = True
+
+        self.auth._change_txt_record = mock.MagicMock(
+            side_effect=ClientError({"Error": {"Code": "foo"}}, "bar"))
+
+        self.auth.cleanup([self.achall])
+
+    def test_parser_arguments(self) -> None:
+        from certbot.util import DeprecatedArgumentAction
+        m = mock.MagicMock()
+        self.auth.add_parser_arguments(m)  # pylint: disable=no-member
+        m.assert_any_call('propagation-seconds', 
action=DeprecatedArgumentAction,
+                          help=mock.ANY, nargs=1)
+
+
+class ClientTest(unittest.TestCase):
+    # pylint: disable=protected-access
+
+    PRIVATE_ZONE = {
+                        "Id": "BAD-PRIVATE",
+                        "Name": "example.com",
+                        "Config": {
+                            "PrivateZone": True
+                        }
+                    }
+
+    EXAMPLE_NET_ZONE = {
+                            "Id": "BAD-WRONG-TLD",
+                            "Name": "example.net",
+                            "Config": {
+                                "PrivateZone": False
+                            }
+                        }
+
+    EXAMPLE_COM_ZONE = {
+                            "Id": "EXAMPLE",
+                            "Name": "example.com",
+                            "Config": {
+                                "PrivateZone": False
+                            }
+                        }
+
+    FOO_EXAMPLE_COM_ZONE = {
+                                "Id": "FOO",
+                                "Name": "foo.example.com",
+                                "Config": {
+                                    "PrivateZone": False
+                                }
+                            }
+
+    def setUp(self):
+        from certbot_dns_route53._internal.dns_route53 import Authenticator
+
+        self.config = mock.MagicMock()
+
+        # Set up dummy credentials for testing
+        os.environ["AWS_ACCESS_KEY_ID"] = "dummy_access_key"
+        os.environ["AWS_SECRET_ACCESS_KEY"] = "dummy_secret_access_key"
+
+        self.client = Authenticator(self.config, "route53")
+
+    def tearDown(self):
+        # Remove the dummy credentials from env vars
+        del os.environ["AWS_ACCESS_KEY_ID"]
+        del os.environ["AWS_SECRET_ACCESS_KEY"]
+
+    def test_find_zone_id_for_domain(self):
+        self.client.r53.get_paginator = mock.MagicMock()
+        self.client.r53.get_paginator().paginate.return_value = [
+            {
+                "HostedZones": [
+                    self.EXAMPLE_NET_ZONE,
+                    self.EXAMPLE_COM_ZONE,
+                ]
+            }
+        ]
+
+        result = self.client._find_zone_id_for_domain("foo.example.com")
+        assert result == "EXAMPLE"
+
+    def test_find_zone_id_for_domain_pagination(self):
+        self.client.r53.get_paginator = mock.MagicMock()
+        self.client.r53.get_paginator().paginate.return_value = [
+            {
+                "HostedZones": [
+                    self.PRIVATE_ZONE,
+                    self.EXAMPLE_COM_ZONE,
+                ]
+            },
+            {
+                "HostedZones": [
+                    self.PRIVATE_ZONE,
+                    self.FOO_EXAMPLE_COM_ZONE,
+                ]
+            }
+        ]
+
+        result = self.client._find_zone_id_for_domain("foo.example.com")
+        assert result == "FOO"
+
+    def test_find_zone_id_for_domain_no_results(self):
+        self.client.r53.get_paginator = mock.MagicMock()
+        self.client.r53.get_paginator().paginate.return_value = []
+
+        with pytest.raises(errors.PluginError):
+            self.client._find_zone_id_for_domain("foo.example.com")
+
+    def test_find_zone_id_for_domain_no_correct_results(self):
+        self.client.r53.get_paginator = mock.MagicMock()
+        self.client.r53.get_paginator().paginate.return_value = [
+            {
+                "HostedZones": [
+                    self.PRIVATE_ZONE,
+                    self.EXAMPLE_NET_ZONE,
+                ]
+            },
+        ]
+
+        with pytest.raises(errors.PluginError):
+            self.client._find_zone_id_for_domain("foo.example.com")
+
+    def test_change_txt_record(self):
+        self.client._find_zone_id_for_domain = mock.MagicMock()
+        self.client.r53.change_resource_record_sets = mock.MagicMock(
+            return_value={"ChangeInfo": {"Id": 1}})
+
+        self.client._change_txt_record("FOO", DOMAIN, "foo")
+
+        call_count = self.client.r53.change_resource_record_sets.call_count
+        assert call_count == 1
+
+    def test_change_txt_record_delete(self):
+        self.client._find_zone_id_for_domain = mock.MagicMock()
+        self.client.r53.change_resource_record_sets = mock.MagicMock(
+            return_value={"ChangeInfo": {"Id": 1}})
+
+        validation = "some-value"
+        validation_record = {"Value": '"{0}"'.format(validation)}
+        self.client._resource_records[DOMAIN] = [validation_record]
+
+        self.client._change_txt_record("DELETE", DOMAIN, validation)
+
+        call_count = self.client.r53.change_resource_record_sets.call_count
+        assert call_count == 1
+        call_args = 
self.client.r53.change_resource_record_sets.call_args_list[0][1]
+        call_args_batch = call_args["ChangeBatch"]["Changes"][0]
+        assert call_args_batch["Action"] == "DELETE"
+        assert call_args_batch["ResourceRecordSet"]["ResourceRecords"] == \
+            [validation_record]
+
+    def test_change_txt_record_multirecord(self):
+        self.client._find_zone_id_for_domain = mock.MagicMock()
+        self.client._get_validation_rrset = mock.MagicMock()
+        self.client._resource_records[DOMAIN] = [
+            {"Value": "\"pre-existing-value\""},
+            {"Value": "\"pre-existing-value-two\""},
+        ]
+        self.client.r53.change_resource_record_sets = mock.MagicMock(
+            return_value={"ChangeInfo": {"Id": 1}})
+
+        self.client._change_txt_record("DELETE", DOMAIN, "pre-existing-value")
+
+        call_count = self.client.r53.change_resource_record_sets.call_count
+        call_args = 
self.client.r53.change_resource_record_sets.call_args_list[0][1]
+        call_args_batch = call_args["ChangeBatch"]["Changes"][0]
+        assert call_args_batch["Action"] == "UPSERT"
+        assert call_args_batch["ResourceRecordSet"]["ResourceRecords"] == \
+            [{"Value": "\"pre-existing-value-two\""}]
+
+        assert call_count == 1
+
+    def test_wait_for_change(self):
+        self.client.r53.get_change = mock.MagicMock(
+            side_effect=[{"ChangeInfo": {"Status": "PENDING"}},
+                         {"ChangeInfo": {"Status": "INSYNC"}}])
+
+        self.client._wait_for_change(1)
+
+        assert self.client.r53.get_change.called
+
+
+if __name__ == "__main__":
+    sys.exit(pytest.main(sys.argv[1:] + [__file__]))  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/PKG-INFO 
new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/PKG-INFO
--- old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/PKG-INFO        
2022-10-04 16:41:17.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/PKG-INFO 
2023-05-09 21:45:01.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: certbot-dns-route53
-Version: 1.31.0
+Version: 2.6.0
 Summary: Route53 DNS Authenticator plugin for Certbot
 Home-page: https://github.com/certbot/certbot
 Author: Certbot Project
@@ -18,6 +18,7 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Security
 Classifier: Topic :: System :: Installation/Setup
@@ -26,4 +27,5 @@
 Classifier: Topic :: Utilities
 Requires-Python: >=3.7
 Provides-Extra: docs
+Provides-Extra: test
 License-File: LICENSE.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/SOURCES.txt 
new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/SOURCES.txt
--- old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/SOURCES.txt     
2022-10-04 16:41:17.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/SOURCES.txt      
2023-05-09 21:45:01.000000000 +0200
@@ -13,10 +13,11 @@
 certbot_dns_route53.egg-info/top_level.txt
 certbot_dns_route53/_internal/__init__.py
 certbot_dns_route53/_internal/dns_route53.py
+certbot_dns_route53/_internal/tests/__init__.py
+certbot_dns_route53/_internal/tests/dns_route53_test.py
 docs/.gitignore
 docs/Makefile
 docs/api.rst
 docs/conf.py
 docs/index.rst
-docs/make.bat
-tests/dns_route53_test.py
\ No newline at end of file
+docs/make.bat
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/requires.txt 
new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/requires.txt
--- old/certbot-dns-route53-1.31.0/certbot_dns_route53.egg-info/requires.txt    
2022-10-04 16:41:17.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/certbot_dns_route53.egg-info/requires.txt     
2023-05-09 21:45:01.000000000 +0200
@@ -1,8 +1,11 @@
 boto3>=1.15.15
 setuptools>=41.6.0
-acme>=1.31.0
-certbot>=1.31.0
+acme>=2.6.0
+certbot>=2.6.0
 
 [docs]
 Sphinx>=1.0
 sphinx_rtd_theme
+
+[test]
+pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-dns-route53-1.31.0/setup.py 
new/certbot-dns-route53-2.6.0/setup.py
--- old/certbot-dns-route53-1.31.0/setup.py     2022-10-04 16:40:42.000000000 
+0200
+++ new/certbot-dns-route53-2.6.0/setup.py      2023-05-09 21:44:37.000000000 
+0200
@@ -4,7 +4,7 @@
 from setuptools import find_packages
 from setuptools import setup
 
-version = '1.31.0'
+version = '2.6.0'
 
 install_requires = [
     'boto3>=1.15.15',
@@ -30,6 +30,10 @@
     'sphinx_rtd_theme',
 ]
 
+test_extras = [
+    'pytest',
+]
+
 setup(
     name='certbot-dns-route53',
     version=version,
@@ -51,6 +55,7 @@
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
         'Topic :: Internet :: WWW/HTTP',
         'Topic :: Security',
         'Topic :: System :: Installation/Setup',
@@ -64,6 +69,7 @@
     keywords=['certbot', 'route53', 'aws'],
     extras_require={
         'docs': docs_extras,
+        'test': test_extras,
     },
     entry_points={
         'certbot.plugins': [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-dns-route53-1.31.0/tests/dns_route53_test.py 
new/certbot-dns-route53-2.6.0/tests/dns_route53_test.py
--- old/certbot-dns-route53-1.31.0/tests/dns_route53_test.py    2022-10-04 
16:40:41.000000000 +0200
+++ new/certbot-dns-route53-2.6.0/tests/dns_route53_test.py     1970-01-01 
01:00:00.000000000 +0100
@@ -1,263 +0,0 @@
-"""Tests for certbot_dns_route53._internal.dns_route53.Authenticator"""
-
-import unittest
-
-from botocore.exceptions import ClientError
-from botocore.exceptions import NoCredentialsError
-try:
-    import mock
-except ImportError: # pragma: no cover
-    from unittest import mock # type: ignore
-
-from certbot import errors
-from certbot.compat import os
-from certbot.plugins import dns_test_common
-from certbot.plugins.dns_test_common import DOMAIN
-
-
-class AuthenticatorTest(unittest.TestCase, 
dns_test_common.BaseAuthenticatorTest):
-    # pylint: disable=protected-access
-
-    def setUp(self):
-        from certbot_dns_route53._internal.dns_route53 import Authenticator
-
-        super().setUp()
-
-        self.config = mock.MagicMock()
-
-        # Set up dummy credentials for testing
-        os.environ["AWS_ACCESS_KEY_ID"] = "dummy_access_key"
-        os.environ["AWS_SECRET_ACCESS_KEY"] = "dummy_secret_access_key"
-
-        self.auth = Authenticator(self.config, "route53")
-
-    def tearDown(self):
-        # Remove the dummy credentials from env vars
-        del os.environ["AWS_ACCESS_KEY_ID"]
-        del os.environ["AWS_SECRET_ACCESS_KEY"]
-
-    def test_perform(self):
-        self.auth._change_txt_record = mock.MagicMock()
-        self.auth._wait_for_change = mock.MagicMock()
-
-        self.auth.perform([self.achall])
-
-        self.auth._change_txt_record.assert_called_once_with("UPSERT",
-                                                             
'_acme-challenge.' + DOMAIN,
-                                                             mock.ANY)
-        self.assertEqual(self.auth._wait_for_change.call_count, 1)
-
-    def test_perform_no_credentials_error(self):
-        self.auth._change_txt_record = 
mock.MagicMock(side_effect=NoCredentialsError)
-
-        self.assertRaises(errors.PluginError,
-                          self.auth.perform,
-                          [self.achall])
-
-    def test_perform_client_error(self):
-        self.auth._change_txt_record = mock.MagicMock(
-            side_effect=ClientError({"Error": {"Code": "foo"}}, "bar"))
-
-        self.assertRaises(errors.PluginError,
-                          self.auth.perform,
-                          [self.achall])
-
-    def test_cleanup(self):
-        self.auth._attempt_cleanup = True
-
-        self.auth._change_txt_record = mock.MagicMock()
-
-        self.auth.cleanup([self.achall])
-
-        self.auth._change_txt_record.assert_called_once_with("DELETE",
-                                                             
'_acme-challenge.'+DOMAIN,
-                                                             mock.ANY)
-
-    def test_cleanup_no_credentials_error(self):
-        self.auth._attempt_cleanup = True
-
-        self.auth._change_txt_record = 
mock.MagicMock(side_effect=NoCredentialsError)
-
-        self.auth.cleanup([self.achall])
-
-    def test_cleanup_client_error(self):
-        self.auth._attempt_cleanup = True
-
-        self.auth._change_txt_record = mock.MagicMock(
-            side_effect=ClientError({"Error": {"Code": "foo"}}, "bar"))
-
-        self.auth.cleanup([self.achall])
-
-
-class ClientTest(unittest.TestCase):
-    # pylint: disable=protected-access
-
-    PRIVATE_ZONE = {
-                        "Id": "BAD-PRIVATE",
-                        "Name": "example.com",
-                        "Config": {
-                            "PrivateZone": True
-                        }
-                    }
-
-    EXAMPLE_NET_ZONE = {
-                            "Id": "BAD-WRONG-TLD",
-                            "Name": "example.net",
-                            "Config": {
-                                "PrivateZone": False
-                            }
-                        }
-
-    EXAMPLE_COM_ZONE = {
-                            "Id": "EXAMPLE",
-                            "Name": "example.com",
-                            "Config": {
-                                "PrivateZone": False
-                            }
-                        }
-
-    FOO_EXAMPLE_COM_ZONE = {
-                                "Id": "FOO",
-                                "Name": "foo.example.com",
-                                "Config": {
-                                    "PrivateZone": False
-                                }
-                            }
-
-    def setUp(self):
-        from certbot_dns_route53._internal.dns_route53 import Authenticator
-
-        self.config = mock.MagicMock()
-
-        # Set up dummy credentials for testing
-        os.environ["AWS_ACCESS_KEY_ID"] = "dummy_access_key"
-        os.environ["AWS_SECRET_ACCESS_KEY"] = "dummy_secret_access_key"
-
-        self.client = Authenticator(self.config, "route53")
-
-    def tearDown(self):
-        # Remove the dummy credentials from env vars
-        del os.environ["AWS_ACCESS_KEY_ID"]
-        del os.environ["AWS_SECRET_ACCESS_KEY"]
-
-    def test_find_zone_id_for_domain(self):
-        self.client.r53.get_paginator = mock.MagicMock()
-        self.client.r53.get_paginator().paginate.return_value = [
-            {
-                "HostedZones": [
-                    self.EXAMPLE_NET_ZONE,
-                    self.EXAMPLE_COM_ZONE,
-                ]
-            }
-        ]
-
-        result = self.client._find_zone_id_for_domain("foo.example.com")
-        self.assertEqual(result, "EXAMPLE")
-
-    def test_find_zone_id_for_domain_pagination(self):
-        self.client.r53.get_paginator = mock.MagicMock()
-        self.client.r53.get_paginator().paginate.return_value = [
-            {
-                "HostedZones": [
-                    self.PRIVATE_ZONE,
-                    self.EXAMPLE_COM_ZONE,
-                ]
-            },
-            {
-                "HostedZones": [
-                    self.PRIVATE_ZONE,
-                    self.FOO_EXAMPLE_COM_ZONE,
-                ]
-            }
-        ]
-
-        result = self.client._find_zone_id_for_domain("foo.example.com")
-        self.assertEqual(result, "FOO")
-
-    def test_find_zone_id_for_domain_no_results(self):
-        self.client.r53.get_paginator = mock.MagicMock()
-        self.client.r53.get_paginator().paginate.return_value = []
-
-        self.assertRaises(errors.PluginError,
-                          self.client._find_zone_id_for_domain,
-                          "foo.example.com")
-
-    def test_find_zone_id_for_domain_no_correct_results(self):
-        self.client.r53.get_paginator = mock.MagicMock()
-        self.client.r53.get_paginator().paginate.return_value = [
-            {
-                "HostedZones": [
-                    self.PRIVATE_ZONE,
-                    self.EXAMPLE_NET_ZONE,
-                ]
-            },
-        ]
-
-        self.assertRaises(errors.PluginError,
-                          self.client._find_zone_id_for_domain,
-                          "foo.example.com")
-
-    def test_change_txt_record(self):
-        self.client._find_zone_id_for_domain = mock.MagicMock()
-        self.client.r53.change_resource_record_sets = mock.MagicMock(
-            return_value={"ChangeInfo": {"Id": 1}})
-
-        self.client._change_txt_record("FOO", DOMAIN, "foo")
-
-        call_count = self.client.r53.change_resource_record_sets.call_count
-        self.assertEqual(call_count, 1)
-
-    def test_change_txt_record_delete(self):
-        self.client._find_zone_id_for_domain = mock.MagicMock()
-        self.client.r53.change_resource_record_sets = mock.MagicMock(
-            return_value={"ChangeInfo": {"Id": 1}})
-
-        validation = "some-value"
-        validation_record = {"Value": '"{0}"'.format(validation)}
-        self.client._resource_records[DOMAIN] = [validation_record]
-
-        self.client._change_txt_record("DELETE", DOMAIN, validation)
-
-        call_count = self.client.r53.change_resource_record_sets.call_count
-        self.assertEqual(call_count, 1)
-        call_args = 
self.client.r53.change_resource_record_sets.call_args_list[0][1]
-        call_args_batch = call_args["ChangeBatch"]["Changes"][0]
-        self.assertEqual(call_args_batch["Action"], "DELETE")
-        self.assertEqual(
-            call_args_batch["ResourceRecordSet"]["ResourceRecords"],
-            [validation_record])
-
-    def test_change_txt_record_multirecord(self):
-        self.client._find_zone_id_for_domain = mock.MagicMock()
-        self.client._get_validation_rrset = mock.MagicMock()
-        self.client._resource_records[DOMAIN] = [
-            {"Value": "\"pre-existing-value\""},
-            {"Value": "\"pre-existing-value-two\""},
-        ]
-        self.client.r53.change_resource_record_sets = mock.MagicMock(
-            return_value={"ChangeInfo": {"Id": 1}})
-
-        self.client._change_txt_record("DELETE", DOMAIN, "pre-existing-value")
-
-        call_count = self.client.r53.change_resource_record_sets.call_count
-        call_args = 
self.client.r53.change_resource_record_sets.call_args_list[0][1]
-        call_args_batch = call_args["ChangeBatch"]["Changes"][0]
-        self.assertEqual(call_args_batch["Action"], "UPSERT")
-        self.assertEqual(
-            call_args_batch["ResourceRecordSet"]["ResourceRecords"],
-            [{"Value": "\"pre-existing-value-two\""}])
-
-        self.assertEqual(call_count, 1)
-
-    def test_wait_for_change(self):
-        self.client.r53.get_change = mock.MagicMock(
-            side_effect=[{"ChangeInfo": {"Status": "PENDING"}},
-                         {"ChangeInfo": {"Status": "INSYNC"}}])
-
-        self.client._wait_for_change(1)
-
-        self.assertTrue(self.client.r53.get_change.called)
-
-
-if __name__ == "__main__":
-    unittest.main()  # pragma: no cover

Reply via email to