@@ -625,3 +625,153 @@ def test_empty_config(self) -> None:
625625 def test_none_config (self ) -> None :
626626 plugin = CloudflarePlugin (None )
627627 assert plugin ._config == {}
628+
629+
630+ # ------------------------------------------------------------------
631+ # auth_check
632+ # ------------------------------------------------------------------
633+
634+
635+ class TestAuthCheckNotConfigured :
636+ def test_missing_endpoint (self ) -> None :
637+ plugin = CloudflarePlugin ({"r2_endpoint" : "" , "r2_bucket" : "b" })
638+ results = plugin .auth_check ()
639+ assert len (results ) == 1
640+ assert results [0 ].service == "Cloudflare R2"
641+ assert results [0 ].status .value == "not_configured"
642+ assert "r2_endpoint" in results [0 ].message
643+
644+ def test_missing_bucket (self ) -> None :
645+ plugin = CloudflarePlugin ({"r2_endpoint" : "https://x.r2.cloudflarestorage.com" , "r2_bucket" : "" })
646+ results = plugin .auth_check ()
647+ assert len (results ) == 1
648+ assert results [0 ].status .value == "not_configured"
649+ assert "r2_bucket" in results [0 ].message
650+
651+ def test_both_missing (self ) -> None :
652+ plugin = CloudflarePlugin ({})
653+ results = plugin .auth_check ()
654+ assert len (results ) == 1
655+ assert results [0 ].status .value == "not_configured"
656+ assert "r2_endpoint" in results [0 ].hint
657+
658+
659+ class TestAuthCheckEnvVarsNotSet :
660+ def test_env_vars_missing (
661+ self ,
662+ plugin_config : dict [str , Any ],
663+ monkeypatch : pytest .MonkeyPatch ,
664+ ) -> None :
665+ monkeypatch .delenv ("R2_ACCESS_KEY_ID" , raising = False )
666+ monkeypatch .delenv ("R2_SECRET_ACCESS_KEY" , raising = False )
667+ plugin = CloudflarePlugin (plugin_config )
668+ results = plugin .auth_check ()
669+ assert len (results ) == 1
670+ assert results [0 ].service == "Cloudflare R2"
671+ assert results [0 ].status .value == "fail"
672+ assert "R2_ACCESS_KEY_ID" in results [0 ].message
673+ assert "R2_SECRET_ACCESS_KEY" in results [0 ].message
674+
675+ def test_env_var_names_in_hint (
676+ self ,
677+ plugin_config : dict [str , Any ],
678+ monkeypatch : pytest .MonkeyPatch ,
679+ ) -> None :
680+ monkeypatch .delenv ("R2_ACCESS_KEY_ID" , raising = False )
681+ monkeypatch .delenv ("R2_SECRET_ACCESS_KEY" , raising = False )
682+ plugin = CloudflarePlugin (plugin_config )
683+ results = plugin .auth_check ()
684+ assert "R2_ACCESS_KEY_ID" in results [0 ].hint
685+ assert "R2_SECRET_ACCESS_KEY" in results [0 ].hint
686+
687+
688+ class TestAuthCheckHeadBucketFails :
689+ @patch ("reeln_cloudflare_plugin.r2._create_client" )
690+ def test_head_bucket_client_error (
691+ self ,
692+ mock_create : Any ,
693+ plugin_config : dict [str , Any ],
694+ r2_env : None ,
695+ ) -> None :
696+ from botocore .exceptions import ClientError
697+
698+ mock_client = mock_create .return_value
699+ mock_client .head_bucket .side_effect = ClientError (
700+ {"Error" : {"Code" : "403" , "Message" : "Forbidden" }},
701+ "HeadBucket" ,
702+ )
703+ plugin = CloudflarePlugin (plugin_config )
704+ results = plugin .auth_check ()
705+ assert len (results ) == 1
706+ assert results [0 ].status .value == "fail"
707+ assert "R2 connection failed" in results [0 ].message
708+ assert "Verify R2 credentials" in results [0 ].hint
709+
710+ @patch ("reeln_cloudflare_plugin.r2._create_client" )
711+ def test_head_bucket_generic_exception (
712+ self ,
713+ mock_create : Any ,
714+ plugin_config : dict [str , Any ],
715+ r2_env : None ,
716+ ) -> None :
717+ mock_client = mock_create .return_value
718+ mock_client .head_bucket .side_effect = RuntimeError ("timeout" )
719+ plugin = CloudflarePlugin (plugin_config )
720+ results = plugin .auth_check ()
721+ assert len (results ) == 1
722+ assert results [0 ].status .value == "fail"
723+ assert "timeout" in results [0 ].message
724+
725+
726+ class TestAuthCheckSuccess :
727+ @patch ("reeln_cloudflare_plugin.r2._create_client" )
728+ def test_connected_ok (
729+ self ,
730+ mock_create : Any ,
731+ plugin_config : dict [str , Any ],
732+ r2_env : None ,
733+ ) -> None :
734+ mock_client = mock_create .return_value
735+ mock_client .head_bucket .return_value = {}
736+ plugin = CloudflarePlugin (plugin_config )
737+ results = plugin .auth_check ()
738+ assert len (results ) == 1
739+ assert results [0 ].service == "Cloudflare R2"
740+ assert results [0 ].status .value == "ok"
741+ assert results [0 ].message == "Connected"
742+ assert results [0 ].identity == "bucket: test-bucket"
743+
744+ @patch ("reeln_cloudflare_plugin.r2._create_client" )
745+ def test_head_bucket_called_with_correct_bucket (
746+ self ,
747+ mock_create : Any ,
748+ plugin_config : dict [str , Any ],
749+ r2_env : None ,
750+ ) -> None :
751+ mock_client = mock_create .return_value
752+ mock_client .head_bucket .return_value = {}
753+ plugin = CloudflarePlugin (plugin_config )
754+ plugin .auth_check ()
755+ mock_client .head_bucket .assert_called_once_with (Bucket = "test-bucket" )
756+
757+
758+ # ------------------------------------------------------------------
759+ # auth_refresh
760+ # ------------------------------------------------------------------
761+
762+
763+ class TestAuthRefresh :
764+ def test_always_returns_fail (self ) -> None :
765+ plugin = CloudflarePlugin ()
766+ results = plugin .auth_refresh ()
767+ assert len (results ) == 1
768+ assert results [0 ].service == "Cloudflare R2"
769+ assert results [0 ].status .value == "fail"
770+ assert "cannot be refreshed" in results [0 ].message
771+
772+ def test_hint_mentions_env_vars (self ) -> None :
773+ plugin = CloudflarePlugin ()
774+ results = plugin .auth_refresh ()
775+ assert "environment variables" in results [0 ].hint
776+ assert "r2_access_key_env" in results [0 ].hint
777+ assert "r2_secret_key_env" in results [0 ].hint
0 commit comments