From 5450de8628b9ff451c4685d009332ee880eb29aa Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Wed, 14 Aug 2024 10:44:38 +0200 Subject: [PATCH] Feat: start testing fs_repository --- dashboard/libs/repository/fs_repository.py | 39 ++++++++------- tests/repository/__init__.py | 0 tests/repository/fs_examples/salary.pdf | Bin 0 -> 44642 bytes .../username-password-recovery-code.xlsx | Bin 0 -> 6118 bytes tests/repository/fs_examples/username.csv | 7 +++ tests/repository/test_fs_repository.py | 46 ++++++++++++++++++ 6 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 tests/repository/__init__.py create mode 100644 tests/repository/fs_examples/salary.pdf create mode 100644 tests/repository/fs_examples/username-password-recovery-code.xlsx create mode 100644 tests/repository/fs_examples/username.csv create mode 100644 tests/repository/test_fs_repository.py diff --git a/dashboard/libs/repository/fs_repository.py b/dashboard/libs/repository/fs_repository.py index c74ac51..2d9d78c 100644 --- a/dashboard/libs/repository/fs_repository.py +++ b/dashboard/libs/repository/fs_repository.py @@ -10,55 +10,60 @@ class FSRepository(AbstractRepository): self.name = name self.basepath = Path(basepath) + assert self.basepath.exists() self._metadata_engine = metadata_engine - def ls(self, dir, only_files=False, only_directories=False, recursive=False) -> list[str]: - dirpath = Path(dir) + def ls( + self, dir="", only_files=False, only_directories=False, recursive=False + ) -> list[str]: + dirpath = self.basepath / dir if only_files: - return [str(f.relative_to(dirpath)) for f in dirpath.iterdir() if not f.is_dir()] + return [ + str(f.relative_to(dirpath)) for f in dirpath.iterdir() if not f.is_dir() + ] if only_directories: if recursive: return [str(f[0].relative_to(dirpath)) for f in dirpath.walk()] - return [str(f.relative_to(dirpath)) for f in dirpath.iterdir() if f.is_dir()] + return [ + str(f.relative_to(dirpath)) for f in dirpath.iterdir() if f.is_dir() + ] return [str(f.relative_to(dirpath)) for f in dirpath.iterdir()] def schemas(self, recursive=True) -> list[str]: - dirpath = self.basepath - return self.ls(dirpath, only_directories=True, recursive=True) + return self.ls("", only_directories=True, recursive=True) - def tables(self, schema:str) -> list[str]: - dirpath = self.basepath / schema - return self.ls(dirpath, only_files=True) + def tables(self, schema: str = ".") -> list[str]: + return self.ls(schema, only_files=True) - def build_table_path(self, table:str, schema:str): + def build_table_path(self, table: str, schema: str): table_path = self.basepath - if schema == '.': + if schema == ".": return table_path / table return table_path / schema / table - def info(self, table:str, schema:str='.'): + def infos(self, table: str, schema: str = "."): table_path = self.build_table_path(table, schema) pass - def read(self, table:str, schema:str='.', read_options={}): + def read(self, table: str, schema: str = ".", read_options={}): table_path = self.build_table_path(table, schema) extension = table_path.suffix - if extension == '.csv': + if extension == ".csv": return pd.read_csv(table_path, **read_options) - if extension == '.xlsx': + if extension == ".xlsx": return pd.read_excel(table_path, **read_options) raise ValueError("Can't open the table") - def write(self, content, table:str, schema:str='.'): + def write(self, content, table: str, schema: str = "."): table_path = self.build_table_path(table, schema) pass - def delete(self, table:str, schema:str='.'): + def delete_table(self, table: str, schema: str = "."): table_path = self.build_table_path(table, schema) pass diff --git a/tests/repository/__init__.py b/tests/repository/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/repository/fs_examples/salary.pdf b/tests/repository/fs_examples/salary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0cbd711539605b297923022ecd28e54f98638a65 GIT binary patch literal 44642 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 literal 0 HcmV?d00001 diff --git a/tests/repository/fs_examples/username-password-recovery-code.xlsx b/tests/repository/fs_examples/username-password-recovery-code.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1723d5cbfa17b25205e4dc51a9fdbdd51688bacf GIT binary patch literal 6118 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 literal 0 HcmV?d00001 diff --git a/tests/repository/fs_examples/username.csv b/tests/repository/fs_examples/username.csv new file mode 100644 index 0000000..006ac8e --- /dev/null +++ b/tests/repository/fs_examples/username.csv @@ -0,0 +1,7 @@ +Username; Identifier;First name;Last name +booker12;9012;Rachel;Booker +grey07;2070;Laura;Grey +johnson81;4081;Craig;Johnson +jenkins46;9346;Mary;Jenkins +smith79;5079;Jamie;Smith + diff --git a/tests/repository/test_fs_repository.py b/tests/repository/test_fs_repository.py new file mode 100644 index 0000000..c005fed --- /dev/null +++ b/tests/repository/test_fs_repository.py @@ -0,0 +1,46 @@ +import shutil +from pathlib import Path + +import pytest + +from dashboard.libs.repository.fs_repository import FSRepository + +EXAMPLE_DIR = "./tests/repository/fs_examples/" + + +@pytest.fixture +def location(tmp_path): + loc = tmp_path + username_loc = loc / "username" + username_loc.mkdir() + salary_loc = loc / "salary" + salary_loc.mkdir() + example_src = Path(EXAMPLE_DIR) + + for f in example_src.glob("*"): + if "username" in str(f): + shutil.copy(f, username_loc) + else: + shutil.copy(f, salary_loc) + + return loc + + +def test_init(location): + repo = FSRepository("example", location) + assert repo.ls() == [ + "username", + "salary", + ] + assert repo.schemas() == [ + ".", + "username", + "salary", + ] + + assert repo.tables() == [] + assert repo.tables("username") == [ + "username.csv", + "username-password-recovery-code.xlsx", + ] + assert repo.tables("salary") == ["salary.pdf"]