Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/80 new upload widget #83

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1c984dd
Add new action to infer a tabular resource schema
aivuk Dec 6, 2022
154d529
Update ckanext/validation/logic.py
aivuk Dec 6, 2022
3b1773c
Remove coverage report
aivuk Dec 6, 2022
a167acb
Merge branch 'feature/76-add-resource-table-schema-infer' of github.c…
aivuk Dec 6, 2022
670d896
correct toolkit imported name
aivuk Dec 6, 2022
1dd1a8a
use new action endpoint with upload widget to create a resource
aivuk Dec 9, 2022
0f45263
remove default resource upload file field
aivuk Dec 10, 2022
124a0f7
Update widget and logic to replace already existing resource files
aivuk Dec 12, 2022
f2af792
Pass the url_type parameter to the ckan-uploader component
aivuk Dec 13, 2022
52ca754
get variables from resource form from hidden inputs
aivuk Dec 13, 2022
e8b5b42
add ckan_uploader snippet
aivuk Dec 13, 2022
6c167a6
Update logic to add another resource after saving one
aivuk Dec 14, 2022
a3c6e27
Add some comments to ckan-uploader-module
aivuk Dec 14, 2022
a225742
Corrects behaviour for uploaded file is not tabular
aivuk Dec 15, 2022
0644e0a
use custom resource_create and resource_update instead of new actions…
aivuk Dec 15, 2022
4c61a0b
remove check for content_length in uploaded resource schema file
aivuk Dec 16, 2022
6ece563
Remove unused actions
amercader Dec 16, 2022
61ff6d4
Use helper to get package id from url
aivuk Jan 12, 2023
d744d2f
Import ckan.model on helpers
aivuk Jan 12, 2023
9c16f8f
Fix blueprints missing imports
aivuk Jan 12, 2023
fb8f7f7
add resource edit new endpoint
aivuk Jan 30, 2023
28eec48
Create resource update endpoint and update ckan-uploader widget
aivuk Feb 1, 2023
547c5ac
Correct default return values for helpers
aivuk Feb 1, 2023
5fb0ec0
Get initialization variables for ckan-uploade its template.
aivuk Feb 1, 2023
8ac15f1
Remove custom resource_form.html template.
aivuk Feb 1, 2023
bfd400a
Get the schema from the returned schema from the action
aivuk Feb 1, 2023
036262e
Stop infering the schema as default in resource create and update
aivuk Feb 1, 2023
25e39ad
Add helpers that are used by ckan_uploader.html template
aivuk Feb 1, 2023
93e1956
Fix template for ckan_uploader adding correctly the variables intial …
aivuk Feb 1, 2023
431beeb
shorter form to compare schema_url value
aivuk Feb 6, 2023
63d8bcd
add logic to switch between file upload and resource url
aivuk Feb 8, 2023
930bb35
Merge branch 'feature/80-new-upload-widget' of github.com:frictionles…
aivuk Feb 8, 2023
a9e5459
remove erroneous test for schema file uploaded size
aivuk Feb 8, 2023
56ab8bb
Remove scrolling to schema json on resource edit
aivuk Feb 8, 2023
ebcc71a
Add basic create/update tests
amercader Feb 23, 2023
78a3351
Bump frictionless to fix schema infer errors
amercader Feb 23, 2023
25dbed6
Revert accidental changes in ckan-uploader.js
amercader Feb 23, 2023
95f31e4
Revert changes made to resource_create / resource_update actions
amercader Feb 23, 2023
9cbb754
Add turn_off_validation context manager
amercader Feb 23, 2023
d9598c5
Don't run validations when creating the draft resource
amercader Feb 23, 2023
3af20e2
Specify format in tests because of ckan/ckan#7415
amercader Feb 23, 2023
9236615
Remove duplicated test
amercader Feb 28, 2023
0198797
Bump responses
amercader Feb 28, 2023
d0f780d
Revert file size check removal in a9e5459
amercader Mar 29, 2023
f990969
Remove debugger
amercader Mar 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ckanext/validation/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def resource_file_update(id, resource_id):
context = {
'user': g.user,
}
data_dict["id"] = resource_id
data_dict["package_id"] = id
resource = get_action("resource_update")(context, data_dict)

Expand Down
347 changes: 347 additions & 0 deletions ckanext/validation/tests/test_uploader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
import io
import pytest
import responses

from ckantoolkit import config
from ckantoolkit.tests.factories import Sysadmin, Dataset, Resource
from ckantoolkit.tests.helpers import call_action
from ckanext.validation.tests.helpers import VALID_CSV, INVALID_CSV


pytestmark = pytest.mark.usefixtures("clean_db", "validation_setup", "mock_uploads")


def _new_resource_upload_url(dataset_id):

url = "/dataset/{}/resource/file".format(dataset_id)

return url


def _edit_resource_upload_url(dataset_id, resource_id):

url = "/dataset/{}/resource/{}/file".format(dataset_id, resource_id)

return url


def _get_env():
user = Sysadmin()
return {"REMOTE_USER": user["name"]}


# Create resources


def test_create_upload_with_schema(app):

dataset = Dataset()

data = {
"upload": (io.BytesIO(bytes(VALID_CSV.encode("utf8"))), "valid.csv"),
}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert len(dataset["resources"]) == 1
assert dataset["resources"][0]["format"] == "CSV"
assert dataset["resources"][0]["url_type"] == "upload"

assert dataset["resources"][0]["schema"] == {
"fields": [
{"name": "a", "type": "integer"},
{"name": "b", "type": "integer"},
{"name": "c", "type": "integer"},
{"name": "d", "type": "integer"},
]
}


def test_create_upload_no_tabular_no_schema(app):

dataset = Dataset()

data = {
"upload": (io.BytesIO(b"test file"), "some.txt"),
}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert len(dataset["resources"]) == 1
assert dataset["resources"][0]["format"] == "TXT"
assert dataset["resources"][0]["url_type"] == "upload"

assert "schema" not in dataset["resources"][0]


@responses.activate
def test_create_url_with_schema(app):

url = "https://example.com/valid.csv"

responses.add(responses.GET, url, body=VALID_CSV)
responses.add_passthru(config["solr_url"])

dataset = Dataset()

data = {"url": url}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert len(dataset["resources"]) == 1
assert dataset["resources"][0]["format"] == "CSV"
assert dataset["resources"][0]["url_type"] is None

assert dataset["resources"][0]["schema"] == {
"fields": [
{"name": "a", "type": "integer"},
{"name": "b", "type": "integer"},
{"name": "c", "type": "integer"},
{"name": "d", "type": "integer"},
]
}


@responses.activate
def test_create_url_no_tabular(app):

url = "https://example.com/some.txt"

responses.add(responses.GET, url, body="some text")
responses.add_passthru(config["solr_url"])

dataset = Dataset()

data = {"url": url}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert len(dataset["resources"]) == 1
assert dataset["resources"][0]["format"] == "TXT"
assert dataset["resources"][0]["url_type"] is None

assert "schema" not in dataset["resources"][0]


# Update resources


def test_update_upload_with_schema(app):

resource = Resource()

data = {
"upload": (io.BytesIO(bytes(VALID_CSV.encode("utf8"))), "valid.csv"),
}

app.post(
url=_edit_resource_upload_url(resource["package_id"], resource["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=resource["id"])

assert resource["format"] == "CSV"
assert resource["url_type"] == "upload"

assert resource["schema"] == {
"fields": [
{"name": "a", "type": "integer"},
{"name": "b", "type": "integer"},
{"name": "c", "type": "integer"},
{"name": "d", "type": "integer"},
]
}


def test_update_upload_no_tabular_no_schema(app):

resource = Resource()

data = {
"upload": (io.BytesIO(b"test file"), "some.txt"),
}

app.post(
url=_edit_resource_upload_url(resource["package_id"], resource["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=resource["id"])

assert resource["format"] == "TXT"
assert resource["url_type"] == "upload"

assert "schema" not in resource


def test_update_updates_schema(app):

dataset = Dataset()

data = {
"upload": (io.BytesIO(bytes(VALID_CSV.encode("utf8"))), "valid.csv"),
}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert dataset["resources"][0]["schema"]

data = {
"upload": (io.BytesIO(b"e,f\n5,6"), "some.other.csv"),
}

app.post(
url=_edit_resource_upload_url(dataset["id"], dataset["resources"][0]["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=dataset["resources"][0]["id"])

assert resource["schema"] == {
"fields": [
{"name": "e", "type": "integer"},
{"name": "f", "type": "integer"},
]
}


def test_update_removes_schema(app):

dataset = Dataset()

data = {
"upload": (io.BytesIO(bytes(VALID_CSV.encode("utf8"))), "valid.csv"),
}

app.post(
url=_new_resource_upload_url(dataset["id"]), extra_environ=_get_env(), data=data
)

dataset = call_action("package_show", id=dataset["id"])

assert dataset["resources"][0]["schema"]

data = {
"upload": (io.BytesIO(b"test file"), "some.txt"),
}

app.post(
url=_edit_resource_upload_url(dataset["id"], dataset["resources"][0]["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=dataset["resources"][0]["id"])

assert "schema" not in resource


def test_update_upload_no_tabular_no_schema(app):

resource = Resource()

data = {
"upload": (io.BytesIO(b"test file"), "some.txt"),
}

app.post(
url=_edit_resource_upload_url(resource["package_id"], resource["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=resource["id"])

assert resource["format"] == "TXT"
assert resource["url_type"] == "upload"

assert "schema" not in resource


@responses.activate
def test_update_url_with_schema(app):
url = "https://example.com/valid.csv"

responses.add(responses.GET, url, body=VALID_CSV)
responses.add_passthru(config["solr_url"])

resource = Resource()

data = {
"url": url,
# CKAN does not refresh the format, see https://github.com/ckan/ckan/issues/7415
"format": "CSV",
}

app.post(
url=_edit_resource_upload_url(resource["package_id"], resource["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=resource["id"])

assert resource["format"] == "CSV"
assert resource["url_type"] is None

assert resource["schema"] == {
"fields": [
{"name": "a", "type": "integer"},
{"name": "b", "type": "integer"},
{"name": "c", "type": "integer"},
{"name": "d", "type": "integer"},
]
}


@responses.activate
def test_update_url_no_tabular_no_schema(app):
url = "https://example.com/some.txt"

responses.add(responses.GET, url, body="some text")
responses.add_passthru(config["solr_url"])

resource = Resource()

data = {
"url": url,
# CKAN does not refresh the format, see https://github.com/ckan/ckan/issues/7415
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the new widget, I'm retrieving the format when the user replace the uploaded resource and changing it on the resource edit form. if the user save the changes the new format is updated but I agree with you, it would be better to do it in the backend

"format": "TXT",
}

app.post(
url=_edit_resource_upload_url(resource["package_id"], resource["id"]),
extra_environ=_get_env(),
data=data,
)

resource = call_action("resource_show", id=resource["id"])

assert resource["format"] == "TXT"
assert resource["url_type"] is None

assert "schema" not in resource
Loading