Skip to content

Commit

Permalink
Upgrade to CKAN 2.10 (#5)
Browse files Browse the repository at this point in the history
Upgrade to CKAN 2.10
  • Loading branch information
avdata99 authored Aug 9, 2023
1 parent becc5b3 commit 20be87a
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 40 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/test-ckan-2.10.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Tests CKAN 2.10 Python 3.10
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
container:
# The CKAN version tag of the Solr and Postgres containers should match
# the one of the container the tests run on.
# You can switch this base image with a custom image tailored to your project
image: openknowledge/ckan-dev:2.10.1
services:
solr:
image: ckan/ckan-solr:2.10-solr8
postgres:
image: ckan/ckan-postgres-dev:2.9
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:3

env:
CKAN_SQLALCHEMY_URL: postgresql://ckan_default:pass@postgres/ckan_test
CKAN_DATASTORE_WRITE_URL: postgresql://datastore_write:pass@postgres/datastore_test
CKAN_DATASTORE_READ_URL: postgresql://datastore_read:pass@postgres/datastore_test
CKAN_SOLR_URL: http://solr:8983/solr/ckan
CKAN_REDIS_URL: redis://redis:6379/1

steps:
- uses: actions/checkout@v2

- name: Flake8
run: |
pip install flake8
flake8 . --count --statistics
- name: Black
run: |
pip install --ignore-installed black
black . --check --diff
- name: Install requirements
# Install any extra requirements your extension has here (dev requirements, other extensions etc)
run: |
# remove when errors with "packaging" package is fixed
pip install setuptools==65.3.0
pip install -r requirements.txt
pip install -r dev-requirements.txt
python3 setup.py develop
- name: Setup extension
# Extra initialization steps
run: |
# Replace default path to CKAN core config file with the one on the container
sed -i -e 's/use = config:.*/use = config:\/srv\/app\/src\/ckan\/test-core.ini/' test.ini
ckan -c test.ini db init
ckan -c test.ini db upgrade -p announcements
- name: Run tests
run: pytest --ckan-ini=test.ini --cov=ckanext.announcements --disable-warnings ckanext/announcements

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Tests
name: Tests CKAN 2.9 Python 3.8
on: [push, pull_request]
jobs:
test:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.1.0 - 2023-08-08
New features:
- CKAN 2.10 compatibility added.

## 0.0.4 - 2022-08-02
New features:
- Validate announcement forms
Expand Down
2 changes: 1 addition & 1 deletion ckanext/announcements/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__VERSION__ = "0.0.4"
__VERSION__ = "0.1.0"
2 changes: 1 addition & 1 deletion ckanext/announcements/assets/css/announcements.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Public
}

.announcement {
padding-bottom: 10px;
padding-bottom: 20px;
margin-bottom: 10px;
}

Expand Down
5 changes: 3 additions & 2 deletions ckanext/announcements/templates/admin/announcements.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ <h2>{{ _('Announcements to all users') }}</h2>
role="button"
class="btn btn-primary"
title="Schedule new message"
data-bs-toggle="modal"
data-toggle="modal"
data-target="#system-message-new"
>Schedule new message</a>
Expand All @@ -33,10 +34,10 @@ <h2>{{ _('Announcements to all users') }}</h2>
<td>{{ h.render_datetime(message.from_date, with_hours=True) }}</td>
<td>{{ h.render_datetime(message.to_date, with_hours=True) }}</td>
<td>
<a href="#system-message-edit-{{ message.id }}" role="button" class="btn btn-info announcement-edit-btn" title="edit" data-toggle="modal" data-target="#system-message-edit-{{ message.id }}">
<a href="#system-message-edit-{{ message.id }}" role="button" class="btn btn-info announcement-edit-btn" title="edit" data-bs-toggle="modal" data-toggle="modal" data-target="#system-message-edit-{{ message.id }}">
<i class="fa fa-edit"></i>
</a>
<a href="#system-message-delete-{{ message.id }}" role="button" class="btn btn-danger announcement-delete-btn" title="delete" data-toggle="modal" data-target="#system-message-delete-{{ message.id }}">
<a href="#system-message-delete-{{ message.id }}" role="button" class="btn btn-danger announcement-delete-btn" title="delete" data-bs-toggle="modal" data-toggle="modal" data-target="#system-message-delete-{{ message.id }}">
<i class="fa fa-trash"></i>
</a>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

<div class="modal-content">
<form method="POST" action="{% url_for 'announcements.delete' %}">

{{ h.csrf_input() if 'csrf_input' in h }}

<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<button type="button" class="close" data-bs-dismiss="modal" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Are you sure you want to delete this announcement?</h3>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
<div class="modal-content">

<form method="POST" action="{% url_for 'announcements.update' %}" class="announcement-form-modal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>

{{ h.csrf_input() if 'csrf_input' in h }}

<div class="modal-header">
<button type="button" class="close" data-bs-dismiss="modal" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Message details</h3>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

<div class="modal-content">
<form method="POST" action="{% url_for 'announcements.create' %}" class="announcement-form-modal">


{{ h.csrf_input() if 'csrf_input' in h }}

<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<button type="button" class="close" data-bs-dismiss="modal" data-dismiss="modal" aria-hidden="true">×</button>
<h3>New Announcement</h3>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="announcements-container container">
{% for announcement in h.get_public_announcements() %}
<div class="alert alert-warning alert-dismissible announcement" role="alert" >
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<button type="button" class="close" data-bs-dismiss="alert" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>

Expand Down
25 changes: 24 additions & 1 deletion ckanext/announcements/tests/factories.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import datetime
import factory
from ckan import model
from ckantoolkit.tests import helpers
from ckantoolkit import check_ckan_version
from ckantoolkit.tests import factories, helpers
from ckanext.announcements.models import Announcement


class UserMulti(factories.User):
"""Multi version CKAN user"""

@factory.post_generation
def token(obj, create, extracted, **kwargs):
if not create:
return
if check_ckan_version(min_version="2.10"):
api_token = factories.APIToken(
user=obj["id"],
expires_in=30,
unit=4,
)
obj["token"] = api_token["token"]
else:
obj["token"] = obj["apikey"]


class SysadminUserMulti(UserMulti):
sysadmin = True


class Announcement(factory.Factory):
class Meta:
model = Announcement
Expand Down
40 changes: 23 additions & 17 deletions ckanext/announcements/tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from types import SimpleNamespace
import pytest

from ckanext.announcements.helpers import (
Expand All @@ -8,31 +9,36 @@
from ckanext.announcements.tests import factories


@pytest.fixture
def an_data():
"""test setup data"""
obj = SimpleNamespace()
obj.old_announcement = factories.Announcement(
message="This is an old message",
from_date=datetime.now() - timedelta(days=7),
to_date=datetime.now() - timedelta(days=6),
)
obj.active_announcement = factories.Announcement(
message="This should be a public message",
from_date=datetime.now() - timedelta(days=1),
to_date=datetime.now() + timedelta(days=1),
)
return obj


@pytest.mark.usefixtures("clean_db", "announcement_migrate")
class TestAnnouncements:
def setup(self):
self.old_announcement = factories.Announcement(
message="This is an old message",
from_date=datetime.now() - timedelta(days=7),
to_date=datetime.now() - timedelta(days=6),
)
self.active_announcement = factories.Announcement(
message="This should be a public message",
from_date=datetime.now() - timedelta(days=1),
to_date=datetime.now() + timedelta(days=1),
)

def test_announcement_saved(self):
def test_announcement_saved(self, an_data):
"""Test single announcement saved correctly"""
assert self.old_announcement.message == "This is an old message"
assert self.old_announcement.status == "active"
assert an_data.old_announcement.message == "This is an old message"
assert an_data.old_announcement.status == "active"

def test_get_all_announcements_helper(self):
def test_get_all_announcements_helper(self, an_data):
"""Test all messages helper"""
ga = get_all_announcements()
assert len(ga) == 2

def test_get_public_announcements_helper(self):
def test_get_public_announcements_helper(self, an_data):
"""Test public messages helper"""
ga = get_public_announcements()
assert len(ga) == 1
Expand Down
30 changes: 19 additions & 11 deletions ckanext/announcements/tests/test_ui.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
from types import SimpleNamespace
import pytest
from ckantoolkit.tests import factories as core_factories
from ckanext.announcements.tests import factories


@pytest.fixture
def an_data():
"""test setup data"""
obj = SimpleNamespace()
# Create CKAN 2.9/2.10 users
obj.regular_user = factories.UserMulti()
obj.sysadmin = factories.SysadminUserMulti()

return obj


@pytest.mark.usefixtures("clean_db", "announcement_migrate", "with_request_context")
class TestAnnouncementsUI:
def setup(self):
self.regular_user = core_factories.User(name="regular")
self.sysadmin = core_factories.Sysadmin(name="sysadmin")

def test_regular_user(self, app):
environ = {"REMOTE_USER": self.regular_user["name"]}
def test_regular_user(self, app, an_data):
environ = {"Authorization": an_data.regular_user["token"]}

resp = app.get("/ckan-admin/announcements", extra_environ=environ)
resp = app.get("/ckan-admin/announcements", headers=environ)
assert resp.status_code == 403

def test_sysadmin_user(self, app):
environ = {"REMOTE_USER": self.sysadmin["name"]}
def test_sysadmin_user(self, app, an_data):
environ = {"Authorization": an_data.sysadmin["token"]}

resp = app.get("/ckan-admin/announcements", extra_environ=environ)
resp = app.get("/ckan-admin/announcements", headers=environ)
assert resp.status_code == 200

0 comments on commit 20be87a

Please sign in to comment.