Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[run]
source = coldfront
omit =
*/migrations/*
*/tests/*
*/venv/*
*/env/*
manage.py
*/settings/*
*/config/*
*/__pycache__/*
*/static/*
*/media/*

[report]
exclude_lines =
pragma: no cover
def __repr__
if self.debug:
if settings.DEBUG
raise AssertionError
raise NotImplementedError
if 0:
if __name__ == .__main__.:
class .*\bProtocol\):
@(abc\.)?abstractmethod

[html]
directory = htmlcov
title = ColdFront Test Coverage Report

[xml]
output = coverage.xml
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,85 @@ Documentation resides in a separate repository. Please request access.
- [Deployment](bootstrap/ansible/README.md)
- [REST API](coldfront/api/README.md)

## Running Tests

### Setting Up the Test Environment

1. **Activate the virtual environment**:
```bash
source coldfront/venv/bin/activate # or wherever your venv is located
```

2. **Install test dependencies** (if not already installed):
```bash
pip install pytest pytest-django pytest-cov factory-boy
```

3. **Configure Django settings for tests**:
The test configuration is already set up in `pytest.ini` and uses `coldfront.config.test_settings` which configures an in-memory SQLite database for fast test execution.

### Running Tests

**Run all tests**:
```bash
pytest coldfront/tests
```

**Run specific test directories**:
```bash
# Unit tests only
pytest coldfront/tests/utils/unit/

# Whitebox integration tests
pytest coldfront/tests/utils/whitebox/

# Blackbox end-to-end tests
pytest coldfront/tests/utils/blackbox/
```

**Run tests with coverage report**:
```bash
pytest coldfront/tests --cov=coldfront --cov-report=html
# View coverage report in htmlcov/index.html
```

**Run tests with specific markers**:
```bash
# Run only unit tests
pytest -m unit

# Run only whitebox tests
pytest -m whitebox

# Run only blackbox tests
pytest -m blackbox
```

**Run tests verbosely**:
```bash
pytest -v # Verbose output
pytest -vv # Very verbose output
pytest -s # Show print statements
```

### Test Structure

- **Unit Tests** (`coldfront/tests/utils/unit/`): Test individual components in isolation
- **Whitebox Tests** (`coldfront/tests/utils/whitebox/`): Test internal behavior and integrations
- **Blackbox Tests** (`coldfront/tests/utils/blackbox/`): Test end-to-end functionality from user perspective

### Test Fixtures

Test fixtures are defined in:
- `coldfront/tests/conftest.py` - Global fixtures for all tests
- `coldfront/tests/utils/conftest.py` - Fixtures specific to utils tests

Key fixtures include:
- `user`, `staff_user`, `superuser` - Different user types
- `project`, `allocation` - Project and allocation instances
- `project_user`, `active_project_user` - User-project relationships
- `django_db_setup` - Session-scoped database setup with required reference data

## License

ColdFront is released under the GPLv3 license. See the LICENSE file.
10 changes: 8 additions & 2 deletions coldfront/config/local_settings.py.sample
Original file line number Diff line number Diff line change
Expand Up @@ -479,10 +479,16 @@ except ImportError:
pass

# Update extra apps based on potentially-updated variables.
EXTRA_APPS += EXTRA_EXTRA_APPS
try:
EXTRA_APPS += EXTRA_EXTRA_APPS
except NameError:
pass # EXTRA_EXTRA_APPS not defined

# Update extra middleware based on potentially-updated variables.
EXTRA_MIDDLEWARE += EXTRA_EXTRA_MIDDLEWARE
try:
EXTRA_MIDDLEWARE += EXTRA_EXTRA_MIDDLEWARE
except NameError:
pass # EXTRA_EXTRA_MIDDLEWARE not defined

# Update logging settings based on potentially-updated variables.
LOGGING['handlers']['file']['filename'] = LOG_PATH
Expand Down
9 changes: 9 additions & 0 deletions coldfront/config/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .settings import *

# Override the DATABASES setting to use SQLite in-memory database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:'
}
}
28 changes: 14 additions & 14 deletions coldfront/config/test_settings.py.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import os

# Define variables that local_settings.py expects before importing
EXTRA_EXTRA_APPS = []
EXTRA_EXTRA_MIDDLEWARE = []
STREAM_LOGS_TO_STDOUT = False
CILOGON_APP_CLIENT_ID = ''
CILOGON_APP_SECRET = ''

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

Expand Down Expand Up @@ -56,18 +63,13 @@ DATABASES = {
LOG_PATH = '/var/log/user_portals/cf_mybrc/cf_mybrc_portal.log'
API_LOG_PATH = '/var/log/user_portals/cf_mybrc/cf_mybrc_api.log'

STREAM_LOGS_TO_STDOUT = False

# A list of admin email addresses to CC when certain requests are approved.
REQUEST_APPROVAL_CC_LIST = ['[email protected]']
# A list of admin email addresses to notify when a project-user removal request
# is processed.
PROJECT_USER_REMOVAL_REQUEST_PROCESSED_EMAIL_ADMIN_LIST = ['[email protected]']

# Extra apps to be included.
EXTRA_EXTRA_APPS = []
# Extra middleware to be included.
EXTRA_EXTRA_MIDDLEWARE = []
# Additional extra apps and middleware are added below

#------------------------------------------------------------------------------
# Django Cache settings
Expand Down Expand Up @@ -134,8 +136,7 @@ SESSION_COOKIE_SECURE = False
# Django All-Auth settings
#------------------------------------------------------------------------------

CILOGON_APP_CLIENT_ID = ''
CILOGON_APP_SECRET = ''
# CILOGON_APP_CLIENT_ID and CILOGON_APP_SECRET are defined above before imports

#------------------------------------------------------------------------------
# django debug toolbar settings
Expand Down Expand Up @@ -170,9 +171,7 @@ FLAGS = {
# Plugin: departments
#------------------------------------------------------------------------------

EXTRA_EXTRA_APPS += [
'coldfront.plugins.departments'
]
EXTRA_EXTRA_APPS.append('coldfront.plugins.departments')

DEPARTMENTS_DEPARTMENT_DISPLAY_NAME = 'Department'
DEPARTMENTS_DEPARTMENT_DATA_SOURCE = 'coldfront.plugins.departments.utils.data_sources.backends.dummy.DummyDataSourceBackend'
Expand All @@ -181,9 +180,7 @@ DEPARTMENTS_DEPARTMENT_DATA_SOURCE = 'coldfront.plugins.departments.utils.data_s
# Plugin: hardware_procurements
#------------------------------------------------------------------------------

EXTRA_EXTRA_APPS += [
'coldfront.plugins.hardware_procurements'
]
EXTRA_EXTRA_APPS.append('coldfront.plugins.hardware_procurements')

HARDWARE_PROCUREMENTS_CONFIG = {
'DATA_SOURCE': 'coldfront.plugins.hardware_procurements.utils.data_sources.backends.dummy.DummyDataSourceBackend',
Expand All @@ -199,3 +196,6 @@ Q_CLUSTER = {
'sync': True,
'timeout': 24 * 60 * 60,
}

# Now import base settings after defining all required variables
from .settings import *
13 changes: 13 additions & 0 deletions coldfront/core/portal/templates/portal/authorized_home.html
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ <h3>My {{ PROGRAM_NAME_SHORT }} Cluster Projects &raquo;</h3>
<th scope="col" class="text-nowrap">
Service Units
</th>
<th scope="col" class="text-nowrap">
Project Access Tracking
</th>
</tr>
</thead>
<tbody>
Expand All @@ -171,6 +174,16 @@ <h3>My {{ PROGRAM_NAME_SHORT }} Cluster Projects &raquo;</h3>
{% include "allocation/cluster_access_badge.html" with status=project.display_status %}
</td>
<td>{{ project.rendered_compute_usage }}</td>
<td>
{% if project.has_tracking %}
<a href="#" data-toggle="modal" data-target="#projectAccessTimelineModal{{ project.pk }}">
View Details
</a>
{% include "portal/project_access_timeline_modal.html" with project=project %}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends "common/base.html" %}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks to be a stale file from a previous PR.

{% load static %}
{% load portal_tags %}

{% block title %}Condo Allocation Entry Detail{% endblock %}

{% block content %}
<div class="container my-4">
<h1>Condo Allocation Entry Detail</h1>
<hr>
<div class="card">
<div class="card-body">
{% for col in decommission_detail_columns %}
<div class="row mb-2">
<div class="col-sm-4 font-weight-bold">{{ col }}:</div>
<div class="col-sm-8">{{ alert.record|get_item:col }}</div>
</div>
{% endfor %}
</div>
</div>
<a href="{% url 'decommission_details' %}" class="btn btn-primary mt-3">Back to Decommission Alerts</a>
</div>
{% endblock %}
22 changes: 22 additions & 0 deletions coldfront/core/portal/templates/portal/progress_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!--Import the progress tracker -->

<div class="modal fade" id="progressModal{{ project.pk }}" tabindex="-1" role="dialog" aria-labelledby="progressModalLabel{{ project.pk }}" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="progressModalLabel{{ project.pk }}">Join Request Progress for {{ project.name }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{% include "progress_tracker.html" with steps=project.progress_steps %}
</div>
<pre>{{ project.progress_steps|safe }}</pre>

<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Loading
Loading