Skip to content

Commit 9318ab4

Browse files
authored
Merge pull request #1123 from NASA-IMPACT/feature/add-github-actions
Automatic Running of Tests On Pull Request
2 parents d5e9166 + 22bde3b commit 9318ab4

File tree

6 files changed

+119
-27
lines changed

6 files changed

+119
-27
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Django Test Suite on PR
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- dev
7+
8+
jobs:
9+
run-tests:
10+
runs-on: ubuntu-latest
11+
12+
services:
13+
docker:
14+
image: docker:24.0.5
15+
options: --privileged
16+
ports:
17+
- 5432:5432
18+
19+
steps:
20+
- name: Check out merged code
21+
uses: actions/checkout@v2
22+
23+
- name: Set up Docker Compose
24+
run: |
25+
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
26+
sudo chmod +x /usr/local/bin/docker-compose
27+
28+
- name: Build the Docker environment
29+
run: docker-compose -f local.yml build
30+
31+
- name: Run test suite
32+
env:
33+
DJANGO_ENV: test
34+
run: docker-compose -f local.yml run --rm django bash ./init.sh
35+
36+
- name: Cleanup
37+
run: docker-compose -f local.yml down --volumes
File renamed without changes.

init.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
echo "Running all test cases across the project..."
3+
4+
# Initialize a failure counter
5+
failure_count=0
6+
7+
# Exclude tests in `document_classifier` and `functional_tests` directories
8+
excluded_dirs="document_classifier functional_tests"
9+
10+
# Find all test files except those in excluded directories
11+
test_files=$(find . -type f -name "test_*.py" | grep -Ev "$(echo $excluded_dirs | sed 's/ /|/g')")
12+
13+
# Run each test file
14+
for test_file in $test_files; do
15+
echo "Running $test_file..."
16+
pytest "$test_file"
17+
18+
# Check the exit status of pytest
19+
if [ $? -ne 0 ]; then
20+
echo "Test failed: $test_file"
21+
failure_count=$((failure_count + 1))
22+
fi
23+
done
24+
25+
# Report the results
26+
if [ $failure_count -ne 0 ]; then
27+
echo "$failure_count test(s) failed."
28+
exit 1
29+
else
30+
echo "All tests passed successfully!"
31+
fi

sde_collections/tests/test_models_collections.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

sde_collections/tests/test_workflow_status_triggers.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,20 @@ def test_quality_check_perfect_triggers_public_query(self, mock_add):
6363

6464
class TestReindexingStatusTransitions(TestCase):
6565
def setUp(self):
66+
# Mock the GitHubHandler to return valid XML content
67+
self.mock_github_handler = patch("sde_collections.models.collection.GitHubHandler").start()
68+
69+
self.mock_github_handler.return_value._get_file_contents.return_value.decoded_content = (
70+
b'<?xml version="1.0" encoding="UTF-8"?>\n'
71+
b"<Sinequa>\n"
72+
b" <KeepHashFragmentInUrl>false</KeepHashFragmentInUrl>\n"
73+
b" <CollectionSelection>Sample Collection</CollectionSelection>\n"
74+
b"</Sinequa>"
75+
)
76+
77+
self.addCleanup(patch.stopall)
78+
79+
# Create the collection with the mock applied
6680
self.collection = CollectionFactory(
6781
workflow_status=WorkflowStatusChoices.QUALITY_CHECK_PERFECT,
6882
reindexing_status=ReindexingStatusChoices.REINDEXING_NOT_NEEDED,

sde_indexing_helper/users/tests/test_views.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
from sde_indexing_helper.users.forms import UserAdminChangeForm
1212
from sde_indexing_helper.users.models import User
13-
from sde_indexing_helper.users.tests.factories import UserFactory
1413
from sde_indexing_helper.users.views import (
1514
UserRedirectView,
1615
UserUpdateView,
@@ -22,39 +21,45 @@
2221

2322
class TestUserUpdateView:
2423
"""
25-
TODO:
26-
extracting view initialization code as class-scoped fixture
27-
would be great if only pytest-django supported non-function-scoped
28-
fixture db access -- this is a work-in-progress for now:
29-
https://github.com/pytest-dev/pytest-django/pull/258
24+
Tests for the UserUpdateView.
3025
"""
3126

32-
def dummy_get_response(self, request: HttpRequest):
27+
@staticmethod
28+
def dummy_get_response(request: HttpRequest):
29+
"""Dummy get_response method for middleware testing."""
3330
return None
3431

3532
def test_get_success_url(self, user: User, rf: RequestFactory):
33+
"""
34+
Test that UserUpdateView redirects to the correct success URL.
35+
"""
3636
view = UserUpdateView()
3737
request = rf.get("/fake-url/")
3838
request.user = user
39-
4039
view.request = request
4140

42-
assert view.get_success_url() == f"/users/{user.username}/"
41+
expected_url = f"/users/{user.username}/"
42+
assert view.get_success_url() == expected_url, f"Expected {expected_url}, got {view.get_success_url()}"
4343

4444
def test_get_object(self, user: User, rf: RequestFactory):
45+
"""
46+
Test that UserUpdateView retrieves the correct user object.
47+
"""
4548
view = UserUpdateView()
4649
request = rf.get("/fake-url/")
4750
request.user = user
48-
4951
view.request = request
5052

5153
assert view.get_object() == user
5254

5355
def test_form_valid(self, user: User, rf: RequestFactory):
56+
"""
57+
Test that form submission in UserUpdateView processes correctly.
58+
"""
5459
view = UserUpdateView()
5560
request = rf.get("/fake-url/")
5661

57-
# Add the session/message middleware to the request
62+
# Add session and message middleware
5863
SessionMiddleware(self.dummy_get_response).process_request(request)
5964
MessageMiddleware(self.dummy_get_response).process_request(request)
6065
request.user = user
@@ -72,26 +77,43 @@ def test_form_valid(self, user: User, rf: RequestFactory):
7277

7378

7479
class TestUserRedirectView:
80+
"""
81+
Tests for the UserRedirectView.
82+
"""
83+
7584
def test_get_redirect_url(self, user: User, rf: RequestFactory):
85+
"""
86+
Test that UserRedirectView redirects to the "sde_collections:list" URL.
87+
"""
7688
view = UserRedirectView()
77-
request = rf.get("/fake-url")
89+
request = rf.get("/fake-url/")
7890
request.user = user
79-
8091
view.request = request
8192

82-
assert view.get_redirect_url() == f"/users/{user.username}/"
93+
expected_url = reverse("sde_collections:list")
94+
assert view.get_redirect_url() == expected_url, f"Expected {expected_url}, got {view.get_redirect_url()}"
8395

8496

8597
class TestUserDetailView:
98+
"""
99+
Tests for the user_detail_view function.
100+
"""
101+
86102
def test_authenticated(self, user: User, rf: RequestFactory):
103+
"""
104+
Test that an authenticated user can access their detail view.
105+
"""
87106
request = rf.get("/fake-url/")
88-
request.user = UserFactory()
107+
request.user = user
89108

90109
response = user_detail_view(request, username=user.username)
91110

92111
assert response.status_code == 200
93112

94113
def test_not_authenticated(self, user: User, rf: RequestFactory):
114+
"""
115+
Test that an unauthenticated user is redirected to the login page.
116+
"""
95117
request = rf.get("/fake-url/")
96118
request.user = AnonymousUser()
97119

0 commit comments

Comments
 (0)