@@ -101,6 +101,25 @@ async def test_azure_blob_storage_io_read_file(azure_blob_storage_io):
101101 assert result == b"Test file content"
102102
103103
104+ @pytest .mark .asyncio
105+ async def test_azure_blob_storage_io_read_file_with_relative_path (azure_blob_storage_io ):
106+ mock_container_client = AsyncMock ()
107+ azure_blob_storage_io ._client_async = mock_container_client
108+
109+ mock_blob_client = AsyncMock ()
110+ mock_blob_stream = AsyncMock ()
111+
112+ mock_container_client .get_blob_client = Mock (return_value = mock_blob_client )
113+ mock_blob_client .download_blob = AsyncMock (return_value = mock_blob_stream )
114+ mock_blob_stream .readall = AsyncMock (return_value = b"Test file content" )
115+ mock_container_client .close = AsyncMock ()
116+
117+ result = await azure_blob_storage_io .read_file ("dir1/dir2/sample.png" )
118+
119+ assert result == b"Test file content"
120+ mock_container_client .get_blob_client .assert_called_once_with (blob = "dir1/dir2/sample.png" )
121+
122+
104123@pytest .mark .asyncio
105124async def test_azure_blob_storage_io_write_file ():
106125 container_url = "https://youraccount.blob.core.windows.net/yourcontainer"
@@ -129,6 +148,29 @@ async def test_azure_blob_storage_io_write_file():
129148 )
130149
131150
151+ @pytest .mark .asyncio
152+ async def test_azure_blob_storage_io_write_file_with_relative_path ():
153+ container_url = "https://youraccount.blob.core.windows.net/yourcontainer"
154+ azure_blob_storage_io = AzureBlobStorageIO (
155+ container_url = container_url , blob_content_type = SupportedContentType .PLAIN_TEXT
156+ )
157+
158+ mock_container_client = AsyncMock ()
159+
160+ with patch .object (azure_blob_storage_io , "_create_container_client_async" , return_value = None ):
161+ azure_blob_storage_io ._client_async = mock_container_client
162+ azure_blob_storage_io ._upload_blob_async = AsyncMock ()
163+
164+ data_to_write = b"Test data"
165+ await azure_blob_storage_io .write_file ("dir1/dir2/testfile.txt" , data_to_write )
166+
167+ azure_blob_storage_io ._upload_blob_async .assert_awaited_with (
168+ file_name = "dir1/dir2/testfile.txt" ,
169+ data = data_to_write ,
170+ content_type = SupportedContentType .PLAIN_TEXT .value ,
171+ )
172+
173+
132174@pytest .mark .asyncio
133175async def test_azure_blob_storage_io_create_container_client_uses_explicit_sas_token ():
134176 container_url = "https://youraccount.blob.core.windows.net/yourcontainer"
@@ -164,6 +206,23 @@ async def test_azure_storage_io_path_exists(azure_blob_storage_io):
164206 assert exists is True
165207
166208
209+ @pytest .mark .asyncio
210+ async def test_azure_storage_io_path_exists_with_relative_path (azure_blob_storage_io ):
211+ mock_container_client = AsyncMock ()
212+ azure_blob_storage_io ._client_async = mock_container_client
213+
214+ mock_blob_client = AsyncMock ()
215+
216+ mock_container_client .get_blob_client = Mock (return_value = mock_blob_client )
217+ mock_blob_client .get_blob_properties = AsyncMock ()
218+ mock_container_client .close = AsyncMock ()
219+
220+ exists = await azure_blob_storage_io .path_exists ("dir1/dir2/blob_name.txt" )
221+
222+ assert exists is True
223+ mock_container_client .get_blob_client .assert_called_once_with (blob = "dir1/dir2/blob_name.txt" )
224+
225+
167226@pytest .mark .asyncio
168227async def test_azure_storage_io_is_file (azure_blob_storage_io ):
169228 azure_blob_storage_io ._client_async = AsyncMock ()
@@ -179,6 +238,24 @@ async def test_azure_storage_io_is_file(azure_blob_storage_io):
179238 assert is_file is True
180239
181240
241+ @pytest .mark .asyncio
242+ async def test_azure_storage_io_is_file_with_relative_path (azure_blob_storage_io ):
243+ mock_container_client = AsyncMock ()
244+ azure_blob_storage_io ._client_async = mock_container_client
245+
246+ mock_blob_client = AsyncMock ()
247+
248+ mock_container_client .get_blob_client = Mock (return_value = mock_blob_client )
249+ mock_blob_properties = Mock (size = 1024 )
250+ mock_blob_client .get_blob_properties = AsyncMock (return_value = mock_blob_properties )
251+ mock_container_client .close = AsyncMock ()
252+
253+ is_file = await azure_blob_storage_io .is_file ("dir1/dir2/blob_name.txt" )
254+
255+ assert is_file is True
256+ mock_container_client .get_blob_client .assert_called_once_with (blob = "dir1/dir2/blob_name.txt" )
257+
258+
182259def test_azure_storage_io_parse_blob_url_valid (azure_blob_storage_io ):
183260 file_path = "https://example.blob.core.windows.net/container/dir1/dir2/blob_name.txt"
184261 container_name , blob_name = azure_blob_storage_io .parse_blob_url (file_path )
@@ -200,3 +277,27 @@ def test_azure_storage_io_parse_blob_url_without_scheme(azure_blob_storage_io):
200277def test_azure_storage_io_parse_blob_url_without_netloc (azure_blob_storage_io ):
201278 with pytest .raises (ValueError , match = "Invalid blob URL" ):
202279 azure_blob_storage_io .parse_blob_url ("https:///container/dir1/blob_name.txt" )
280+
281+
282+ def test_resolve_blob_name_with_full_url (azure_blob_storage_io ):
283+ result = azure_blob_storage_io ._resolve_blob_name ("https://account.blob.core.windows.net/container/dir1/file.txt" )
284+ assert result == "dir1/file.txt"
285+
286+
287+ def test_resolve_blob_name_with_relative_path (azure_blob_storage_io ):
288+ assert azure_blob_storage_io ._resolve_blob_name ("dir1/dir2/file.txt" ) == "dir1/dir2/file.txt"
289+
290+
291+ def test_resolve_blob_name_with_simple_filename (azure_blob_storage_io ):
292+ assert azure_blob_storage_io ._resolve_blob_name ("file.txt" ) == "file.txt"
293+
294+
295+ def test_resolve_blob_name_normalizes_backslashes (azure_blob_storage_io ):
296+ assert azure_blob_storage_io ._resolve_blob_name ("dir1\\ dir2\\ file.txt" ) == "dir1/dir2/file.txt"
297+
298+
299+ def test_resolve_blob_name_with_path_object (azure_blob_storage_io ):
300+ from pathlib import PurePosixPath
301+
302+ result = azure_blob_storage_io ._resolve_blob_name (PurePosixPath ("dir1/dir2/file.txt" ))
303+ assert result == "dir1/dir2/file.txt"
0 commit comments