Skip to content

Commit

Permalink
improve github mock, improve deletion test and fix deletion endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
perierc committed Nov 9, 2023
1 parent 373ef6c commit 61ecbde
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 70 deletions.
4 changes: 2 additions & 2 deletions backend/editor/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,11 +615,11 @@ async def delete_taxonomy_project(self, branch, taxonomy_name):
"""

delete_query = """
MATCH (n:PROJECT {taxonomy_name: $taxonomy_name, branch: $branch})
MATCH (n:PROJECT {taxonomy_name: $taxonomy_name, branch_name: $branch_name})
DELETE n
"""
result = await get_current_transaction().run(
delete_query, taxonomy_name=taxonomy_name, branch=branch
delete_query, taxonomy_name=taxonomy_name, branch_name=branch
)
summary = await result.consume()
count = summary.counters.nodes_deleted
Expand Down
4 changes: 2 additions & 2 deletions backend/editor/github_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from textwrap import dedent

from github import Github
import github

from . import settings

Expand All @@ -21,7 +21,7 @@ def init_driver_and_repo(self):
"""
Initalize connection to Github with an access token
"""
github_driver = Github(settings.access_token)
github_driver = github.Github(settings.access_token)
repo = github_driver.get_repo(settings.repo_uri)
return repo

Expand Down
26 changes: 13 additions & 13 deletions backend/sample/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ def dump_nodes(session, file):
"""Dump all nodes from the database to a JSON file."""
node_count = session.run("MATCH (n) RETURN count(n)").single()[0]
for i, node in enumerate(session.run("MATCH (n) RETURN n")):
node_dict = dict(node['n'])
node_dict = dict(node["n"])
print(node_dict)
labels_list = list(node['n'].labels)
node_dict['labels'] = labels_list
labels_list = list(node["n"].labels)
node_dict["labels"] = labels_list
if i < node_count - 1:
f.write(json.dumps(node_dict, ensure_ascii=False) + ',')
f.write(json.dumps(node_dict, ensure_ascii=False) + ",")
else:
f.write(json.dumps(node_dict, ensure_ascii=False))

Expand All @@ -32,35 +32,35 @@ def dump_relations(session, file):
"""Dump all relationships from the database to a JSON file."""
rels_count = session.run("MATCH (n)-[r]->(m) RETURN count(r)").single()[0]
for i, rel in enumerate(session.run("MATCH (n)-[r]->(m) RETURN r")):
start_node_id = rel['r'].nodes[0].id
end_node_id = rel['r'].nodes[1].id
start_node_id = rel["r"].nodes[0].id
end_node_id = rel["r"].nodes[1].id
start_node = session.run(
"MATCH (n) WHERE id(n) = $id RETURN n", {"id": start_node_id}
).single()["n"]["id"]
end_node = session.run(
"MATCH (n) WHERE id(n) = $id RETURN n", {"id": end_node_id}
).single()["n"]["id"]
rel_dict = {rel['r'].type: [start_node, end_node]}
rel_dict = {rel["r"].type: [start_node, end_node]}
if i < rels_count - 1:
f.write(json.dumps(rel_dict, ensure_ascii=False) + ',')
f.write(json.dumps(rel_dict, ensure_ascii=False) + ",")
else:
f.write(json.dumps(rel_dict, ensure_ascii=False))


def get_options(args=None):
"""Parse command line arguments."""
parser = argparse.ArgumentParser(description='Dump Neo4J database to JSON file')
parser.add_argument('--url', default=DEFAULT_URL, help='Neo4J database bolt URL')
parser.add_argument('file', help='JSON file name to dump')
parser = argparse.ArgumentParser(description="Dump Neo4J database to JSON file")
parser.add_argument("--url", default=DEFAULT_URL, help="Neo4J database bolt URL")
parser.add_argument("file", help="JSON file name to dump")
return parser.parse_args(args)


if __name__ == "__main__":
options = get_options()
session = get_session(options.url)
with open(options.file, 'w') as f:
with open(options.file, "w") as f:
f.write('{"nodes": [')
dump_nodes(session, f)
f.write('], "relations": [')
dump_relations(session, f)
f.write(']}')
f.write("]}")
26 changes: 15 additions & 11 deletions backend/sample/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,24 @@
def get_session(uri=DEFAULT_URL):
return GraphDatabase.driver(uri).session()


def clean_db(session):
session.run("""match (p) detach delete(p)""")


def add_node(node, session):
labels = node.pop("labels", [])
query = f"CREATE (n:{','.join(labels)} $data)"
session.run(query, data=node)


def add_link(rel, session):
if len(rel) != 1 and len(next(iter(rel.values()))) != 2:
raise ValueError(f"""
raise ValueError(
f"""
Expecting relations to by dict like {{"rel_name": ["node1", "node2"]}}, got {rel}
""".trim())
""".trim()
)
for rel_name, (from_id, to_id) in rel.items():
query = f"""
MATCH(source) WHERE source.id = $from_id
Expand All @@ -46,15 +51,14 @@ def load_jsonl(file_path, session):


def get_options(args=None):
parser = argparse.ArgumentParser(description='Import json file to Neo4J database')
parser.add_argument('--url', default=DEFAULT_URL, help='Neo4J database bolt URL')
parser.add_argument('file', help='Json file to import')
parser = argparse.ArgumentParser(description="Import json file to Neo4J database")
parser.add_argument("--url", default=DEFAULT_URL, help="Neo4J database bolt URL")
parser.add_argument("file", help="Json file to import")
parser.add_argument(
'--reset', default=False, action="store_true",
help='Clean all database before importing'
"--reset", default=False, action="store_true", help="Clean all database before importing"
)
parser.add_argument('--yes', default=False, action="store_true",
help='Assume yes to all questions'
parser.add_argument(
"--yes", default=False, action="store_true", help="Assume yes to all questions"
)
return parser.parse_args(args)

Expand All @@ -66,7 +70,7 @@ def confirm_clean_db(session):
response = input(f"You are about to remove {num_nodes} nodes, are you sure ? [y/N]: ")
return response.lower() in ("y", "yes")


if __name__ == "__main__":
options = get_options()
session = get_session(options.url)
Expand All @@ -76,4 +80,4 @@ def confirm_clean_db(session):
sys.exit(1)
else:
clean_db(session)
load_jsonl(options.file, session)
load_jsonl(options.file, session)
74 changes: 32 additions & 42 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,63 @@ def test_setup(neo4j):
session.run(query)


@pytest.fixture
def github_mock(mocker):
github_mock = mocker.patch("github.Github")
github_mock.return_value.get_repo.return_value.get_branches.return_value = [mocker.Mock()]
return github_mock


def test_hello(client):
response = client.get("/")

assert response.status_code == 200
assert response.json() == {"message": "Hello user! Tip: open /docs or /redoc for documentation"}


def test_ping(client):
response = client.get("/ping")

assert response.status_code == 200
assert response.json().get("ping").startswith("pong @")


def test_import_from_github(client, mocker):
mocker.patch("editor.api.TaxonomyGraph.is_branch_unique", return_value=True)
def test_import_from_github(client, github_mock, mocker):
# We mock the TaxonomyGraph.import_from_github method,
# which downloads the taxonomy file from a Github URL
mocker.patch("editor.api.TaxonomyGraph.import_from_github", return_value=True)

response = client.post(
"/test/testing_branch/import",
json={"description": "test_description"},
)

assert response.status_code == 200
assert response.json() is True


def test_upload_taxonomy(client, mocker):
mocker.patch("editor.api.TaxonomyGraph.is_branch_unique", return_value=True)
mocker.patch("editor.api.TaxonomyGraph.upload_taxonomy", return_value=True)
def test_upload_taxonomy(client, github_mock):
with open("tests/data/test.txt", "rb") as f:
response = client.post(
"/test_taxonomy/test_branch/upload",
files={"file": f},
data={"description": "test_description"},
)

assert response.status_code == 200
assert response.json() is True


def test_add_taxonomy_duplicate_branch_name(client, mocker):
mocker.patch("editor.api.TaxonomyGraph.is_branch_unique", return_value=False)
def test_add_taxonomy_duplicate_branch_name(client, github_mock):
github_mock.return_value.get_repo.return_value.get_branches.return_value[0].name = "test_branch"

with open("tests/data/test.txt", "rb") as f:
response = client.post(
"/test_taxonomy_2/test_branch/upload",
files={"file": f},
data={"description": "test_description"},
)

assert response.status_code == 409
assert response.json() == {"detail": "branch_name: Branch name should be unique!"}

Expand All @@ -68,52 +81,29 @@ def test_add_taxonomy_invalid_branch_name(client):
files={"file": f},
data={"description": "test_description"},
)

assert response.status_code == 400
assert response.json() == {"detail": "branch_name: Enter a valid branch name!"}


def test_add_taxonomy_duplicate_project_name(client, mocker):
mocker.patch("editor.api.TaxonomyGraph.does_project_exist", return_value=True)
def test_add_taxonomy_duplicate_project_name(client, github_mock):
test_upload_taxonomy(client, github_mock)

with open("tests/data/test.txt", "rb") as f:
response = client.post(
"/test_taxonomy/test_branch/upload",
files={"file": f},
data={"description": "test_description"},
)

assert response.status_code == 409
assert response.json() == {"detail": "Project already exists!"}


def test_delete_project(neo4j, client):
with neo4j.session() as session:
create_project = """
CREATE (n:PROJECT)
SET n.id = 'test_project'
SET n.taxonomy_name = 'test_taxonomy_name'
SET n.branch = 'test_branch'
SET n.description = 'test_description'
SET n.status = 'OPEN'
SET n.project_name = 'p_test_taxonomy_name_test_branch_name'
SET n.created_at = datetime()
"""

create_project2 = """
CREATE (n:PROJECT)
SET n.id = 'test_project2'
SET n.taxonomy_name = 'test_taxonomy_name2'
SET n.branch = 'test_branch2'
SET n.description = 'test_description2'
SET n.status = 'OPEN'
SET n.project_name = 'p_test_taxonomy_name_test_branch_name2'
SET n.created_at = datetime()
"""
session.run(create_project)
session.run(create_project2)

response = client.delete("/test_taxonomy_name/test_branch/delete")
assert response.status_code == 200
assert response.json() == {"message": "Deleted 1 projects"}

response = client.delete("/test_taxonomy_name2/test_branch2/delete")
assert response.status_code == 200
assert response.json() == {"message": "Deleted 1 projects"}
def test_delete_project(client, github_mock):
test_upload_taxonomy(client, github_mock)

response = client.delete("/test_taxonomy/test_branch/delete")

assert response.status_code == 200
assert response.json() == {"message": "Deleted 1 projects"}

0 comments on commit 61ecbde

Please sign in to comment.