fixed tests w/ burnettk
This commit is contained in:
parent
66bd628c58
commit
38428cb6a4
|
@ -1248,7 +1248,7 @@ paths:
|
||||||
parameters:
|
parameters:
|
||||||
- name: file_contents_hash
|
- name: file_contents_hash
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: false
|
||||||
description: The hash of the file contents that originally came with the file.
|
description: The hash of the file contents that originally came with the file.
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
|
||||||
from dataclasses import field
|
from dataclasses import field
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional
|
from typing import Any
|
||||||
|
|
||||||
from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum
|
from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum
|
||||||
from spiffworkflow_backend.models.spec_reference import SpecReference
|
from spiffworkflow_backend.models.spec_reference import SpecReference
|
||||||
|
@ -71,10 +71,10 @@ class File:
|
||||||
type: str
|
type: str
|
||||||
last_modified: datetime
|
last_modified: datetime
|
||||||
size: int
|
size: int
|
||||||
references: Optional[list[SpecReference]] = None
|
references: list[SpecReference] | None = None
|
||||||
file_contents: Optional[bytes] = None
|
file_contents: bytes | None = None
|
||||||
process_model_id: Optional[str] = None
|
process_model_id: str | None = None
|
||||||
file_contents_hash: Optional[str] = None
|
file_contents_hash: str | None = None
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""__post_init__."""
|
"""__post_init__."""
|
||||||
|
@ -88,7 +88,7 @@ class File:
|
||||||
content_type: str,
|
content_type: str,
|
||||||
last_modified: datetime,
|
last_modified: datetime,
|
||||||
file_size: int,
|
file_size: int,
|
||||||
) -> "File":
|
) -> File:
|
||||||
"""From_file_system."""
|
"""From_file_system."""
|
||||||
instance = cls(
|
instance = cls(
|
||||||
name=file_name,
|
name=file_name,
|
||||||
|
@ -103,5 +103,5 @@ class File:
|
||||||
def serialized(self) -> dict[str, Any]:
|
def serialized(self) -> dict[str, Any]:
|
||||||
dictionary = self.__dict__
|
dictionary = self.__dict__
|
||||||
if isinstance(self.file_contents, bytes):
|
if isinstance(self.file_contents, bytes):
|
||||||
dictionary['file_contents'] = self.file_contents.decode('utf-8')
|
dictionary["file_contents"] = self.file_contents.decode("utf-8")
|
||||||
return dictionary
|
return dictionary
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""APIs for dealing with process groups, process models, and process instances."""
|
"""APIs for dealing with process groups, process models, and process instances."""
|
||||||
from hashlib import sha256
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
from hashlib import sha256
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
@ -245,9 +245,13 @@ def process_model_list(
|
||||||
return make_response(jsonify(response_json), 200)
|
return make_response(jsonify(response_json), 200)
|
||||||
|
|
||||||
|
|
||||||
def process_model_file_update(modified_process_model_identifier: str, file_name: str, file_contents_hash: str) -> flask.wrappers.Response:
|
def process_model_file_update(
|
||||||
|
modified_process_model_identifier: str, file_name: str, file_contents_hash: str
|
||||||
|
) -> flask.wrappers.Response:
|
||||||
message = f"User: {g.user.username} clicked save for"
|
message = f"User: {g.user.username} clicked save for"
|
||||||
return _create_or_update_process_model_file(modified_process_model_identifier, message, 200, file_contents_hash=file_contents_hash)
|
return _create_or_update_process_model_file(
|
||||||
|
modified_process_model_identifier, message, 200, file_contents_hash=file_contents_hash
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def process_model_file_delete(modified_process_model_identifier: str, file_name: str) -> flask.wrappers.Response:
|
def process_model_file_delete(modified_process_model_identifier: str, file_name: str) -> flask.wrappers.Response:
|
||||||
|
@ -297,10 +301,8 @@ def process_model_file_show(modified_process_model_identifier: str, file_name: s
|
||||||
files = SpecFileService.get_files(process_model, file_name)
|
files = SpecFileService.get_files(process_model, file_name)
|
||||||
if len(files) == 0:
|
if len(files) == 0:
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
error_code="unknown file",
|
error_code="process_model_file_not_found",
|
||||||
message=(
|
message=f"File {file_name} not found in workflow {process_model_identifier}.",
|
||||||
f"No information exists for file {file_name} it does not exist in workflow {process_model_identifier}."
|
|
||||||
),
|
|
||||||
status_code=404,
|
status_code=404,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -477,7 +479,7 @@ def _create_or_update_process_model_file(
|
||||||
modified_process_model_identifier: str,
|
modified_process_model_identifier: str,
|
||||||
message_for_git_commit: str,
|
message_for_git_commit: str,
|
||||||
http_status_to_return: int,
|
http_status_to_return: int,
|
||||||
file_contents_hash: Optional[str],
|
file_contents_hash: Optional[str] = None,
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
"""_create_or_update_process_model_file."""
|
"""_create_or_update_process_model_file."""
|
||||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||||
|
@ -499,13 +501,18 @@ def _create_or_update_process_model_file(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if file_contents_hash is not None:
|
||||||
current_file_contents_bytes = SpecFileService.get_data(process_model, request_file.filename)
|
current_file_contents_bytes = SpecFileService.get_data(process_model, request_file.filename)
|
||||||
if current_file_contents_bytes and file_contents_hash:
|
if current_file_contents_bytes and file_contents_hash:
|
||||||
current_file_contents_hash = sha256(current_file_contents_bytes).hexdigest()
|
current_file_contents_hash = sha256(current_file_contents_bytes).hexdigest()
|
||||||
if current_file_contents_hash != file_contents_hash:
|
if current_file_contents_hash != file_contents_hash:
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
error_code="process_model_file_has_changed",
|
error_code="process_model_file_has_changed",
|
||||||
message=f"Process model file: {request_file.filename} was already changed by someone else. Please reload before making changes.",
|
message=(
|
||||||
|
f"Process model file: {request_file.filename} was already changed by someone else. If you made"
|
||||||
|
" changes you do not want to lose, click the Download button and make sure your changes are"
|
||||||
|
" in the resulting file. If you do not need your changes, you can safely reload this page."
|
||||||
|
),
|
||||||
status_code=409,
|
status_code=409,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,6 @@ class BaseTest:
|
||||||
process_group_id: str,
|
process_group_id: str,
|
||||||
display_name: str = "",
|
display_name: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Create_process_group."""
|
|
||||||
process_group = ProcessGroup(id=process_group_id, display_name=display_name, display_order=0, admin=False)
|
process_group = ProcessGroup(id=process_group_id, display_name=display_name, display_order=0, admin=False)
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/v1.0/process-groups",
|
"/v1.0/process-groups",
|
||||||
|
@ -138,7 +137,6 @@ class BaseTest:
|
||||||
primary_file_name: Optional[str] = None,
|
primary_file_name: Optional[str] = None,
|
||||||
user: Optional[UserModel] = None,
|
user: Optional[UserModel] = None,
|
||||||
) -> TestResponse:
|
) -> TestResponse:
|
||||||
"""Create_process_model."""
|
|
||||||
if process_model_id is not None:
|
if process_model_id is not None:
|
||||||
# make sure we have a group
|
# make sure we have a group
|
||||||
process_group_id, _ = os.path.split(process_model_id)
|
process_group_id, _ = os.path.split(process_model_id)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import io
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from hashlib import sha256
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
@ -232,7 +233,6 @@ class TestProcessApi(BaseTest):
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_primary_process_id_updates_via_xml."""
|
|
||||||
process_group_id = "test_group"
|
process_group_id = "test_group"
|
||||||
process_model_id = "sample"
|
process_model_id = "sample"
|
||||||
process_model_identifier = f"{process_group_id}/{process_model_id}"
|
process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||||
|
@ -258,10 +258,11 @@ class TestProcessApi(BaseTest):
|
||||||
updated_bpmn_file_data_string = bpmn_file_data_string.replace(old_string, new_string)
|
updated_bpmn_file_data_string = bpmn_file_data_string.replace(old_string, new_string)
|
||||||
updated_bpmn_file_data_bytes = bytearray(updated_bpmn_file_data_string, "utf-8")
|
updated_bpmn_file_data_bytes = bytearray(updated_bpmn_file_data_string, "utf-8")
|
||||||
data = {"file": (io.BytesIO(updated_bpmn_file_data_bytes), bpmn_file_name)}
|
data = {"file": (io.BytesIO(updated_bpmn_file_data_bytes), bpmn_file_name)}
|
||||||
|
file_contents_hash = sha256(bpmn_file_data_bytes).hexdigest()
|
||||||
|
|
||||||
modified_process_model_id = process_model_identifier.replace("/", ":")
|
modified_process_model_id = process_model_identifier.replace("/", ":")
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/process-models/{modified_process_model_id}/files/{bpmn_file_name}",
|
f"/v1.0/process-models/{modified_process_model_id}/files/{bpmn_file_name}?file_contents_hash={file_contents_hash}",
|
||||||
data=data,
|
data=data,
|
||||||
follow_redirects=True,
|
follow_redirects=True,
|
||||||
content_type="multipart/form-data",
|
content_type="multipart/form-data",
|
||||||
|
@ -780,13 +781,12 @@ class TestProcessApi(BaseTest):
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_process_model_file_update."""
|
|
||||||
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
||||||
modified_process_model_id = process_model_identifier.replace("/", ":")
|
modified_process_model_id = process_model_identifier.replace("/", ":")
|
||||||
|
|
||||||
data = {"key1": "THIS DATA"}
|
data = {"key1": "THIS DATA"}
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg",
|
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg?file_contents_hash=does_not_matter",
|
||||||
data=data,
|
data=data,
|
||||||
follow_redirects=True,
|
follow_redirects=True,
|
||||||
content_type="multipart/form-data",
|
content_type="multipart/form-data",
|
||||||
|
@ -803,13 +803,12 @@ class TestProcessApi(BaseTest):
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_process_model_file_update."""
|
|
||||||
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
||||||
modified_process_model_id = process_model_identifier.replace("/", ":")
|
modified_process_model_id = process_model_identifier.replace("/", ":")
|
||||||
|
|
||||||
data = {"file": (io.BytesIO(b""), "random_fact.svg")}
|
data = {"file": (io.BytesIO(b""), "random_fact.svg")}
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg",
|
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg?file_contents_hash=does_not_matter",
|
||||||
data=data,
|
data=data,
|
||||||
follow_redirects=True,
|
follow_redirects=True,
|
||||||
content_type="multipart/form-data",
|
content_type="multipart/form-data",
|
||||||
|
@ -827,30 +826,22 @@ class TestProcessApi(BaseTest):
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_process_model_file_update."""
|
|
||||||
process_group_id = "test_group"
|
process_group_id = "test_group"
|
||||||
process_group_description = "Test Group"
|
process_model_id = "simple_form"
|
||||||
process_model_id = "random_fact"
|
|
||||||
process_model_identifier = f"{process_group_id}/{process_model_id}"
|
process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||||
self.create_process_group_with_api(client, with_super_admin_user, process_group_id, process_group_description)
|
bpmn_file_name = "simple_form.json"
|
||||||
self.create_process_model_with_api(
|
load_test_spec(
|
||||||
client,
|
|
||||||
process_model_id=process_model_identifier,
|
process_model_id=process_model_identifier,
|
||||||
user=with_super_admin_user,
|
process_model_source_directory="simple_form",
|
||||||
)
|
|
||||||
|
|
||||||
bpmn_file_name = "random_fact.bpmn"
|
|
||||||
original_file = load_test_spec(
|
|
||||||
process_model_id=process_model_id,
|
|
||||||
bpmn_file_name=bpmn_file_name,
|
|
||||||
process_model_source_directory="random_fact",
|
|
||||||
)
|
)
|
||||||
|
bpmn_file_data_bytes = self.get_test_data_file_contents(bpmn_file_name, process_model_id)
|
||||||
|
file_contents_hash = sha256(bpmn_file_data_bytes).hexdigest()
|
||||||
|
|
||||||
modified_process_model_id = process_model_identifier.replace("/", ":")
|
modified_process_model_id = process_model_identifier.replace("/", ":")
|
||||||
new_file_contents = b"THIS_IS_NEW_DATA"
|
new_file_contents = b"THIS_IS_NEW_DATA"
|
||||||
data = {"file": (io.BytesIO(new_file_contents), "random_fact.svg")}
|
data = {"file": (io.BytesIO(new_file_contents), bpmn_file_name)}
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg",
|
f"/v1.0/process-models/{modified_process_model_id}/files/{bpmn_file_name}?file_contents_hash={file_contents_hash}",
|
||||||
data=data,
|
data=data,
|
||||||
follow_redirects=True,
|
follow_redirects=True,
|
||||||
content_type="multipart/form-data",
|
content_type="multipart/form-data",
|
||||||
|
@ -862,12 +853,11 @@ class TestProcessApi(BaseTest):
|
||||||
assert response.json["file_contents"] is not None
|
assert response.json["file_contents"] is not None
|
||||||
|
|
||||||
response = client.get(
|
response = client.get(
|
||||||
f"/v1.0/process-models/{modified_process_model_id}/files/random_fact.svg",
|
f"/v1.0/process-models/{modified_process_model_id}/files/simple_form.json",
|
||||||
headers=self.logged_in_headers(with_super_admin_user),
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
updated_file = json.loads(response.get_data(as_text=True))
|
updated_file = json.loads(response.get_data(as_text=True))
|
||||||
assert original_file != updated_file
|
|
||||||
assert updated_file["file_contents"] == new_file_contents.decode()
|
assert updated_file["file_contents"] == new_file_contents.decode()
|
||||||
|
|
||||||
def test_process_model_file_delete_when_bad_process_model(
|
def test_process_model_file_delete_when_bad_process_model(
|
||||||
|
@ -879,9 +869,6 @@ class TestProcessApi(BaseTest):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_process_model_file_update."""
|
"""Test_process_model_file_update."""
|
||||||
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
process_model_identifier = self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
||||||
# self.create_spec_file(client, user=with_super_admin_user)
|
|
||||||
|
|
||||||
# process_model = load_test_spec("random_fact")
|
|
||||||
bad_process_model_identifier = f"x{process_model_identifier}"
|
bad_process_model_identifier = f"x{process_model_identifier}"
|
||||||
modified_bad_process_model_identifier = bad_process_model_identifier.replace("/", ":")
|
modified_bad_process_model_identifier = bad_process_model_identifier.replace("/", ":")
|
||||||
response = client.delete(
|
response = client.delete(
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
Favorite,
|
Favorite,
|
||||||
Edit,
|
Edit,
|
||||||
View,
|
View,
|
||||||
ArrowRight,
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} from '@carbon/icons-react';
|
} from '@carbon/icons-react';
|
||||||
import {
|
import {
|
||||||
|
|
Loading…
Reference in New Issue