Skip to content

Commit

Permalink
Release 2024.06.1 (#2182)
Browse files Browse the repository at this point in the history
  • Loading branch information
thekaveman authored Jun 24, 2024
2 parents 3281457 + 658502e commit 4508f89
Show file tree
Hide file tree
Showing 61 changed files with 1,248 additions and 405 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"dockerComposeFile": ["../compose.yml"],
"service": "dev",
"runServices": ["dev", "docs", "server"],
"workspaceFolder": "/home/calitp/app",
"workspaceFolder": "/calitp/app",
"postStartCommand": ["/bin/bash", "bin/reset_db.sh"],
"postAttachCommand": ["/bin/bash", ".devcontainer/postAttach.sh"],
"customizations": {
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/postAttach.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -eu

# initialize pre-commit

git config --global --add safe.directory /home/calitp/app
git config --global --add safe.directory /calitp/app
pre-commit install --overwrite
6 changes: 3 additions & 3 deletions .github/workflows/add-to-project-dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
add-to-project-dependabot:
runs-on: ubuntu-latest
# see https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions#responding-to-events
if: github.actor == 'dependabot[bot]'
if: github.actor == 'dependabot[bot]' || github.actor == 'pre-commit-ci[bot]'
steps:
- uses: actions/add-to-project@main
with:
Expand All @@ -18,7 +18,7 @@ jobs:
- uses: EndBug/project-fields@v2
with:
operation: set
fields: Effort
values: 1
fields: Effort,Status
values: 1,In review
project_url: https://github.com/orgs/cal-itp/projects/${{ secrets.GH_PROJECT }}
github_token: ${{ secrets.GH_PROJECTS_TOKEN }}
48 changes: 48 additions & 0 deletions .github/workflows/check-migrations-and-messages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Check for up-to-date Django migrations and messages
on: [push, pull_request]

jobs:
check-migrations-and-messages:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4

- name: Install system packages
run: |
sudo apt-get update -y
sudo apt-get install -y gettext
- uses: actions/setup-python@v5
with:
python-version-file: .github/workflows/.python-version
cache: pip
cache-dependency-path: "**/pyproject.toml"

- name: Install Python dependencies
run: pip install -e .[dev,test]

- name: Run ./bin/makemigrations.sh
run: |
if ./bin/makemigrations.sh | grep -q 'No changes detected';
then
exit 0;
else
exit 1;
fi
- name: Run ./bin/makemessages.sh
run: |
./bin/makemessages.sh
set -x # show commands
git add benefits
# message files are up-to-date if the only differences are from the updated timestamp
if echo $(git diff --cached --shortstat) | grep -q '2 files changed, 2 insertions(+), 2 deletions(-)';
then
exit 0;
else
exit 1;
fi
1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
name: CodeQL Analyze
runs-on: ubuntu-latest
needs: setup
if: ${{ needs.setup.outputs.languages != '[]' }}
permissions:
actions: read
contents: read
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ jobs:
context: .
file: appcontainer/Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.ref_name }}
ghcr.io/${{ github.repository }}:${{ github.sha }}
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

- name: Deploy to Azure Web App
uses: azure/webapps-deploy@v2
with:
app-name: ${{ vars.AZURE_WEBAPP_NAME }}
images: ghcr.io/${{ github.repository }}:${{ github.sha }}
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
2 changes: 1 addition & 1 deletion .github/workflows/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
uses: actions/checkout@v4

- name: Download coverage report
uses: dawidd6/action-download-artifact@v3
uses: dawidd6/action-download-artifact@v6
with:
workflow: tests-pytest.yml
branch: dev
Expand Down
2 changes: 1 addition & 1 deletion appcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RUN python -m pip install --upgrade pip

# overwrite default nginx.conf
COPY appcontainer/nginx.conf /etc/nginx/nginx.conf
COPY appcontainer/proxy.conf /home/calitp/run/proxy.conf
COPY appcontainer/proxy.conf /calitp/run/proxy.conf

# copy source files
COPY manage.py manage.py
Expand Down
8 changes: 4 additions & 4 deletions appcontainer/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ http {
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
server unix:/home/calitp/run/gunicorn.sock fail_timeout=0;
server unix:/calitp/run/gunicorn.sock fail_timeout=0;
}

# maps $binary_ip_address to $limit variable if request is of type POST
Expand Down Expand Up @@ -67,7 +67,7 @@ http {

# path for static files
location /static/ {
alias /home/calitp/app/static/;
alias /calitp/app/static/;
expires 1y;
add_header Cache-Control public;
}
Expand All @@ -81,12 +81,12 @@ http {
# case-insensitive regex matches path
location ~* ^/(eligibility/confirm)$ {
limit_req zone=rate_limit;
include /home/calitp/run/proxy.conf;
include /calitp/run/proxy.conf;
}

# app path
location @proxy_to_app {
include /home/calitp/run/proxy.conf;
include /calitp/run/proxy.conf;
}
}
}
2 changes: 1 addition & 1 deletion benefits/core/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def unique_values(original_list):
def _agency_context(agency):
return {
"eligibility_index_url": agency.eligibility_index_url,
"help_templates": unique_values([v.help_template for v in agency.active_verifiers if v.help_template is not None]),
"help_templates": unique_values([v.help_template for v in agency.active_verifiers if v.help_template]),
"info_url": agency.info_url,
"long_name": agency.long_name,
"phone": agency.phone,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.0.3 on 2024-05-17 19:49

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("core", "0010_alter_secret_name_field_blank"),
]

operations = [
migrations.RemoveField(
model_name="transitagency",
name="enrollment_success_template",
),
migrations.AddField(
model_name="eligibilitytype",
name="enrollment_success_template",
field=models.TextField(default="enrollment/success.html"),
),
]
21 changes: 12 additions & 9 deletions benefits/core/migrations/local_fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"fields": {
"name": "senior",
"label": "(MST) Senior Discount",
"group_id": "group123"
"group_id": "group123",
"enrollment_success_template": "enrollment/success--mst.html"
}
},
{
Expand All @@ -78,7 +79,8 @@
"fields": {
"name": "veteran",
"label": "(MST) Veteran Discount",
"group_id": "group123"
"group_id": "group123",
"enrollment_success_template": "enrollment/success--mst.html"
}
},
{
Expand All @@ -88,7 +90,8 @@
"name": "courtesy_card",
"label": "(MST) Courtesy Card Discount",
"group_id": "group123",
"enrollment_index_template": "enrollment/index--agency-card.html"
"enrollment_index_template": "enrollment/index--agency-card.html",
"enrollment_success_template": "enrollment/success--mst-courtesy-card.html"
}
},
{
Expand All @@ -97,7 +100,8 @@
"fields": {
"name": "senior",
"label": "(SacRT) Senior Discount",
"group_id": "group123"
"group_id": "group123",
"enrollment_success_template": "enrollment/success--sacrt.html"
}
},
{
Expand All @@ -106,7 +110,8 @@
"fields": {
"name": "senior",
"label": "(SBMTD) Senior Discount",
"group_id": "group123"
"group_id": "group123",
"enrollment_success_template": "enrollment/success--sbmtd.html"
}
},
{
Expand All @@ -116,7 +121,8 @@
"name": "mobility_pass",
"label": "(SBMTD) Mobility Pass Discount",
"group_id": "group123",
"enrollment_index_template": "enrollment/index--agency-card.html"
"enrollment_index_template": "enrollment/index--agency-card.html",
"enrollment_success_template": "enrollment/success--sbmtd-mobility-pass.html"
}
},
{
Expand Down Expand Up @@ -340,7 +346,6 @@
"jws_signing_alg": "RS256",
"index_template": "core/index--mst.html",
"eligibility_index_template": "eligibility/index--mst.html",
"enrollment_success_template": "enrollment/success--mst.html",
"eligibility_types": [1, 7, 2, 3],
"eligibility_verifiers": [1, 7, 2, 3]
}
Expand All @@ -363,7 +368,6 @@
"jws_signing_alg": "RS256",
"index_template": "core/index--sacrt.html",
"eligibility_index_template": "eligibility/index--sacrt.html",
"enrollment_success_template": "enrollment/success--sacrt.html",
"eligibility_types": [4],
"eligibility_verifiers": [4]
}
Expand All @@ -386,7 +390,6 @@
"jws_signing_alg": "RS256",
"index_template": "core/index--sbmtd.html",
"eligibility_index_template": "eligibility/index--sbmtd.html",
"enrollment_success_template": "enrollment/success--sbmtd.html",
"eligibility_types": [5, 6],
"eligibility_verifiers": [5, 6]
}
Expand Down
2 changes: 1 addition & 1 deletion benefits/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class EligibilityType(models.Model):
expiration_reenrollment_days = models.PositiveSmallIntegerField(null=True, blank=True)
enrollment_index_template = models.TextField(default="enrollment/index.html")
reenrollment_error_template = models.TextField(null=True, blank=True)
enrollment_success_template = models.TextField(default="enrollment/success.html")

def __str__(self):
return self.label
Expand Down Expand Up @@ -276,7 +277,6 @@ class TransitAgency(models.Model):
jws_signing_alg = models.TextField()
index_template = models.TextField()
eligibility_index_template = models.TextField()
enrollment_success_template = models.TextField()

def __str__(self):
return self.long_name
Expand Down
1 change: 1 addition & 0 deletions benefits/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ def to_url(self, agency):
path("<agency:agency>", views.agency_index, name="agency_index"),
path("<agency:agency>/publickey", views.agency_public_key, name="agency_public_key"),
path("logged_out", views.logged_out, name="logged_out"),
path("error", views.server_error, name="server-error"),
]
1 change: 1 addition & 0 deletions benefits/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
ROUTE_ELIGIBILITY = "eligibility:index"
ROUTE_HELP = "core:help"
ROUTE_LOGGED_OUT = "core:logged_out"
ROUTE_SERVER_ERROR = "core:server-error"

TEMPLATE_INDEX = "core/index.html"
TEMPLATE_AGENCY = "core/agency-index.html"
Expand Down
14 changes: 14 additions & 0 deletions benefits/enrollment/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ def __init__(self, request, status, error=None, payment_group=None):
self.update_event_properties(payment_group=payment_group)


class FailedAccessTokenRequestEvent(core.Event):
"""Analytics event representing a failure to acquire an access token for card tokenization."""

def __init__(self, request, status_code=None):
super().__init__(request, "failed access token request")
if status_code is not None:
self.update_event_properties(status_code=status_code)


def returned_error(request, error):
"""Send the "returned enrollment" analytics event with an error status and message."""
core.send_event(ReturnedEnrollmentEvent(request, status="error", error=error))
Expand All @@ -29,3 +38,8 @@ def returned_retry(request):
def returned_success(request, payment_group):
"""Send the "returned enrollment" analytics event with a success status."""
core.send_event(ReturnedEnrollmentEvent(request, status="success", payment_group=payment_group))


def failed_access_token_request(request, status_code=None):
"""Send the "failed access token request" analytics event with the response status code."""
core.send_event(FailedAccessTokenRequestEvent(request, status_code=status_code))
4 changes: 2 additions & 2 deletions benefits/enrollment/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ class CardTokenizeSuccessForm(forms.Form):
class CardTokenizeFailForm(forms.Form):
"""Form to indicate card tokenization failure to server."""

id = "form-card-tokenize-fail"
method = "POST"

def __init__(self, action_url, *args, **kwargs):
def __init__(self, action_url, id, *args, **kwargs):
# init super with an empty data dict
# binds and makes immutable this form's data
# since there are no form fields, the form is also marked as valid
super().__init__({}, *args, **kwargs)
self.id = id
self.action_url = action_url
13 changes: 12 additions & 1 deletion benefits/enrollment/templates/enrollment/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ <h1 class="pb-lg-8 pb-4">
$.ajax({ dataType: "script", attrs: { nonce: "{{ request.csp_nonce }}"}, url: "{{ card_tokenize_url }}" })
.done(function() {
$.get("{{ access_token_url }}", function(data) {
if (data.redirect) {
// https://stackoverflow.com/a/42469170
// use 'assign' because 'replace' was giving strange Back button behavior
window.location.assign(data.redirect);
return; // exit early so the rest of this function doesn't execute
}

$(".loading").remove();
// remove invisible and add back visible, so we aren't left with
// a div with an empty class attribute
Expand Down Expand Up @@ -87,7 +94,11 @@ <h1 class="pb-lg-8 pb-4">
/* 400 or 500 will return. */
amplitude.getInstance().logEvent(closedEvent, {status: "error", error: response});

var form = $("form#{{ form_retry }}");
if (response.status >= 500) {
var form = $("form#{{ form_system_error }}");
} else {
var form = $("form#{{ form_server_error }}");
}
form.submit();
},
onCancel: function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends "enrollment/success.html" %}
{% load i18n %}

{% block headline-message %}
{% blocktranslate trimmed %}
You can now use your contactless card to tap to ride with a reduced fare!
{% endblocktranslate %}
{% endblock headline-message %}

{% block success-message %}
{% blocktranslate trimmed %}
Your contactless card is now enrolled in an MST Courtesy Card transit benefit. When boarding an MST bus, tap this card and you will be
charged a reduced fare. You will need to re-enroll if you choose to change the card you use to pay for transit service.
{% endblocktranslate %}
{% endblock success-message %}

{% block thank-you-message %}
{% blocktranslate trimmed %}
You were not charged anything today. Thank you for using Cal-ITP Benefits!
{% endblocktranslate %}
{% endblock thank-you-message %}
Loading

0 comments on commit 4508f89

Please sign in to comment.