Skip to content

Commit

Permalink
makedirs and listdir correctly work with paths started with /
Browse files Browse the repository at this point in the history
refactored tests
----------------

Signed-off-by: Alexander Piskun <[email protected]>
  • Loading branch information
bigcat88 authored Sep 1, 2023
1 parent 8be2f81 commit ad6ba5d
Show file tree
Hide file tree
Showing 33 changed files with 1,110 additions and 1,177 deletions.
27 changes: 6 additions & 21 deletions .github/workflows/analysis-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ concurrency:
env:
NEXTCLOUD_URL: "http://localhost:8080"
APP_ID: "nc_py_api"
APP_PORT: 9009
APP_VERSION: "1.0.0"
APP_SECRET: "tC6vkwPhcppjMykD1r0n9NlI95uJMBYjs5blpIcA1PAdoPDmc5qoAjaBAkyocZ6E"
APP_PORT: 9009
NC_AUTH_USER: "admin"
NC_AUTH_PASS: "adminpassword"

Expand Down Expand Up @@ -133,10 +133,7 @@ jobs:
python3 tests/_install_wait.py http://127.0.0.1:$APP_PORT/heartbeat "\"status\":\"ok\"" 15 0.5
python3 tests/_app_security_checks.py http://127.0.0.1:$APP_PORT
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
sh nc_py_api/scripts/ci_register.sh "$APP_ID" "$APP_VERSION" "$APP_SECRET" "localhost" "$APP_PORT"
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -293,10 +290,7 @@ jobs:
python3 tests/_install_wait.py http://127.0.0.1:$APP_PORT/heartbeat "\"status\":\"ok\"" 15 0.5
python3 tests/_app_security_checks.py http://127.0.0.1:$APP_PORT
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
sh nc_py_api/scripts/ci_register.sh "$APP_ID" "$APP_VERSION" "$APP_SECRET" "localhost" "$APP_PORT"
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -438,10 +432,7 @@ jobs:
python3 tests/_install_wait.py http://127.0.0.1:$APP_PORT/heartbeat "\"status\":\"ok\"" 15 0.5
python3 tests/_app_security_checks.py http://127.0.0.1:$APP_PORT
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
sh nc_py_api/scripts/ci_register.sh "$APP_ID" "$APP_VERSION" "$APP_SECRET" "localhost" "$APP_PORT"
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -560,10 +551,7 @@ jobs:
python3 tests/_install_wait.py http://127.0.0.1:$APP_PORT/heartbeat "\"status\":\"ok\"" 15 0.5
python3 tests/_app_security_checks.py http://127.0.0.1:$APP_PORT
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
sh nc_py_api/scripts/ci_register.sh "$APP_ID" "$APP_VERSION" "$APP_SECRET" "localhost" "$APP_PORT"
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -814,10 +802,7 @@ jobs:
python3 tests/_install_wait.py http://127.0.0.1:$APP_PORT/heartbeat "\"status\":\"ok\"" 15 0.5
python3 tests/_app_security_checks.py http://127.0.0.1:$APP_PORT
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"protocol\":\"http\",\"port\":$APP_PORT,\"system_app\":1}" \
-e --force-scopes
sh nc_py_api/scripts/ci_register.sh "$APP_ID" "$APP_VERSION" "$APP_SECRET" "localhost" "$APP_PORT"
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="register_nc_py_api" type="PythonConfigurationType" factoryName="Python">
<configuration default="false" name="register_nc_py_api (28)" type="PythonConfigurationType" factoryName="Python">
<module name="nc_py_api" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file.

## [0.0.43 - 2023-09-0x]

### Fixed

- `makedirs` correctly work with paths started with `/`
- `listdir` correctly handles `exclude_self=True` when input `path` starts with `/`

## [0.0.42 - 2023-08-30]

### Added
Expand Down
2 changes: 1 addition & 1 deletion nc_py_api/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Version of nc_py_api."""

__version__ = "0.0.42"
__version__ = "0.0.43.dev0"
3 changes: 2 additions & 1 deletion nc_py_api/files/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ def makedirs(self, path: Union[str, FsNode], exist_ok=False) -> Optional[FsNode]
"""
_path = ""
path = path.user_path if isinstance(path, FsNode) else path
path = path.lstrip("/")
result = None
for i in Path(path).parts:
_path = os.path.join(_path, i)
Expand Down Expand Up @@ -443,7 +444,7 @@ def _listdir(
)
if exclude_self:
for index, v in enumerate(result):
if v.user_path.rstrip("/") == path.rstrip("/"):
if v.user_path.rstrip("/") == path.strip("/"):
del result[index]
break
return result
Expand Down
9 changes: 9 additions & 0 deletions scripts/ci_register.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

# Parameters:
# APP_ID, VERSION, SECRET, HOST, PORT

php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register "$1" manual_install --json-info \
"{\"appid\":\"$1\",\"name\":\"$1\",\"daemon_config_name\":\"manual_install\",\"version\":\"$2\",\"secret\":\"$3\",\"host\":\"$4\",\"scopes\":{\"required\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\"],\"optional\":[\"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\", \"TALK_BOT\"]},\"port\":$5,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
Empty file added tests/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion tests/_tests_at_the_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys
from subprocess import Popen

from _install_wait import check_heartbeat
from ._install_wait import check_heartbeat

# These tests will be run separate, and at the end of all other tests.

Expand Down
Empty file added tests/actual_tests/__init__.py
Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import pytest
from conftest import NC_APP

from nc_py_api import NextcloudExceptionNotFound

from ..conftest import NC_APP

if NC_APP is None:
pytest.skip("Need App mode", allow_module_level=True)

Expand Down
File renamed without changes.
117 changes: 117 additions & 0 deletions tests/actual_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import contextlib
from io import BytesIO
from os import environ, path
from random import randbytes

import pytest
from PIL import Image

from nc_py_api import Nextcloud, NextcloudApp, NextcloudException, _session # noqa

from ..conftest import NC_CLIENT

_TEST_FAILED_INCREMENTAL: dict[str, dict[tuple[int, ...], str]] = {}


@pytest.fixture(scope="session")
def rand_bytes() -> bytes:
"""Returns 64 bytes from `test_64_bytes.bin` file."""
return randbytes(64)


def init_filesystem_for_user(nc_any, rand_bytes):
"""
/test_empty_dir
/test_empty_dir_in_dir/test_empty_child_dir
/test_dir
/test_dir/subdir/
/test_dir/subdir/test_empty_text.txt
/test_dir/subdir/test_64_bytes.bin
/test_dir/subdir/test_12345_text.txt
/test_dir/subdir/test_generated_image.png
/test_dir/test_empty_child_dir/
/test_dir/test_empty_text.txt
/test_dir/test_64_bytes.bin
/test_dir/test_12345_text.txt
/test_dir/test_generated_image.png
/test_empty_text.txt
/test_64_bytes.bin
/test_12345_text.txt
/test_generated_image.png
/test_dir_tmp
"""
clean_filesystem_for_user(nc_any)
im = BytesIO()
Image.linear_gradient("L").resize((768, 768)).save(im, format="PNG")
nc_any.files.mkdir("/test_empty_dir")
nc_any.files.makedirs("/test_empty_dir_in_dir/test_empty_child_dir")
nc_any.files.makedirs("/test_dir/subdir")
nc_any.files.mkdir("/test_dir/test_empty_child_dir/")
nc_any.files.mkdir("/test_dir_tmp")

def init_folder(folder: str = ""):
nc_any.files.upload(path.join(folder, "test_empty_text.txt"), content=b"")
nc_any.files.upload(path.join(folder, "test_64_bytes.bin"), content=rand_bytes)
nc_any.files.upload(path.join(folder, "test_12345_text.txt"), content="12345")
im.seek(0)
nc_any.files.upload(path.join(folder, "test_generated_image.png"), content=im.read())

init_folder()
init_folder("test_dir")
init_folder("test_dir/subdir")


def clean_filesystem_for_user(nc_any):
clean_up_list = [
"test_empty_dir",
"test_empty_dir_in_dir",
"test_dir",
"test_dir_tmp",
"test_empty_text.txt",
"test_64_bytes.bin",
"test_12345_text.txt",
"test_generated_image.png",
]
for i in clean_up_list:
nc_any.files.delete(i, not_fail=True)


@pytest.fixture(autouse=True, scope="session")
def tear_up_down(nc_any, rand_bytes):
if NC_CLIENT:
# create two additional groups
environ["TEST_GROUP_BOTH"] = "test_nc_py_api_group_both"
environ["TEST_GROUP_USER"] = "test_nc_py_api_group_user"
with contextlib.suppress(NextcloudException):
NC_CLIENT.users_groups.delete(environ["TEST_GROUP_BOTH"])
with contextlib.suppress(NextcloudException):
NC_CLIENT.users_groups.delete(environ["TEST_GROUP_USER"])
NC_CLIENT.users_groups.create(group_id=environ["TEST_GROUP_BOTH"])
NC_CLIENT.users_groups.create(group_id=environ["TEST_GROUP_USER"])
# create two additional users
environ["TEST_ADMIN_ID"] = "test_nc_py_api_admin"
environ["TEST_ADMIN_PASS"] = "az1dcaNG4c42"
environ["TEST_USER_ID"] = "test_nc_py_api_user"
environ["TEST_USER_PASS"] = "DC89GvaR42lk"
with contextlib.suppress(NextcloudException):
NC_CLIENT.users.delete(environ["TEST_ADMIN_ID"])
with contextlib.suppress(NextcloudException):
NC_CLIENT.users.delete(environ["TEST_USER_ID"])
NC_CLIENT.users.create(
environ["TEST_ADMIN_ID"], password=environ["TEST_ADMIN_PASS"], groups=["admin", environ["TEST_GROUP_BOTH"]]
)
NC_CLIENT.users.create(
environ["TEST_USER_ID"],
password=environ["TEST_USER_PASS"],
groups=[environ["TEST_GROUP_BOTH"], environ["TEST_GROUP_USER"]],
)
init_filesystem_for_user(nc_any, rand_bytes) # currently we initialize filesystem only for admin

yield

clean_filesystem_for_user(nc_any)
if NC_CLIENT:
NC_CLIENT.users.delete(environ["TEST_ADMIN_ID"])
NC_CLIENT.users.delete(environ["TEST_USER_ID"])
NC_CLIENT.users_groups.delete(environ["TEST_GROUP_BOTH"])
NC_CLIENT.users_groups.delete(environ["TEST_GROUP_USER"])
Loading

0 comments on commit ad6ba5d

Please sign in to comment.