Skip to content

Commit

Permalink
Separate payment processors (test) (#1366)
Browse files Browse the repository at this point in the history
  • Loading branch information
thekaveman committed Apr 18, 2023
2 parents ee28110 + a7f6081 commit 8eb97d7
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 115 deletions.
7 changes: 2 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
FROM benefits_client:latest

# install devcontainer requirements
COPY .devcontainer/requirements.txt .devcontainer/requirements.txt
RUN pip install -r .devcontainer/requirements.txt
RUN pip install -e .[dev,test]

# docs requirements are in a separate file for the GitHub Action
COPY docs/requirements.txt docs/requirements.txt
RUN pip install -r docs/requirements.txt

COPY tests/pytest/requirements.txt tests/pytest/requirements.txt
RUN pip install -r tests/pytest/requirements.txt

# install pre-commit environments in throwaway Git repository
# https://stackoverflow.com/a/68758943
COPY .pre-commit-config.yaml .
Expand Down
1 change: 1 addition & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"bungcip.better-toml",
"batisteo.vscode-django",
"bpruitt-goddard.mermaid-markdown-syntax-highlighting",
"eamodio.gitlens",
Expand Down
4 changes: 0 additions & 4 deletions .devcontainer/requirements.txt

This file was deleted.

1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
.flake8
.*ignore
*.db
*.egg-info
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/appcontainer" # main requirements.txt
directory: "/" # pyproject.toml
schedule:
interval: "daily"
commit-message:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/labeler-deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ on:
branches: [dev]
types: [opened]
paths:
- '.github/workflows/deploy-*.yml'
- 'benefits/**'
- 'bin/**'
- ".github/workflows/deploy-*.yml"
- "benefits/**"
- "bin/**"
- Dockerfile
- requirements.txt
- pyproject.toml

jobs:
label-deployment-dev:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests-pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
with:
python-version-file: .github/workflows/.python-version
cache: pip
cache-dependency-path: "**/requirements.txt"
cache-dependency-path: "**/pyproject.toml"

- name: Install Python dependencies
run: pip install -r appcontainer/requirements.txt -r tests/pytest/requirements.txt
run: pip install -e .[test]

- name: Run setup
run: ./bin/init.sh
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ repos:
args: ["--maxkb=1500"]

- repo: https://github.com/psf/black
rev: 23.1.0
rev: 23.3.0
hooks:
- id: black
types:
Expand All @@ -61,6 +61,6 @@ repos:
types_or: [javascript, css]

- repo: https://github.com/Riverside-Healthcare/djLint
rev: v1.19.16
rev: v1.19.17
hooks:
- id: djlint-django
14 changes: 7 additions & 7 deletions appcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
FROM ghcr.io/cal-itp/docker-python-web:main

# install python dependencies
COPY appcontainer/requirements.txt requirements.txt
RUN pip install -r requirements.txt
# upgrade pip
RUN python -m pip install --upgrade pip

# copy Django utility script
# copy source files
COPY manage.py manage.py
COPY bin bin
COPY benefits benefits
COPY pyproject.toml pyproject.toml

# copy source files
COPY bin/ bin/
COPY benefits/ benefits/
RUN pip install -e .

# ensure $USER can compile messages in the locale directories
USER root
Expand Down
7 changes: 0 additions & 7 deletions appcontainer/requirements.txt

This file was deleted.

78 changes: 55 additions & 23 deletions benefits/core/migrations/0002_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,34 @@ def load_data(app, *args, **kwargs):
-----END CERTIFICATE-----
"""

payment_processor_client_cert = PemData.objects.create(
text=os.environ.get("PAYMENT_PROCESSOR_CLIENT_CERT", dummy_cert_text),
label="Payment processor client certificate",
mst_payment_processor_client_cert = PemData.objects.create(
text=os.environ.get("MST_PAYMENT_PROCESSOR_CLIENT_CERT", dummy_cert_text),
label="MST payment processor client certificate",
)

payment_processor_client_cert_private_key = PemData.objects.create(
text=os.environ.get("PAYMENT_PROCESSOR_CLIENT_CERT_PRIVATE_KEY", client_private_key.text),
label="Payment processor client certificate private key",
mst_payment_processor_client_cert_private_key = PemData.objects.create(
text=os.environ.get("MST_PAYMENT_PROCESSOR_CLIENT_CERT_PRIVATE_KEY", client_private_key.text),
label="MST payment processor client certificate private key",
)

payment_processor_client_cert_root_ca = PemData.objects.create(
text=os.environ.get("PAYMENT_PROCESSOR_CLIENT_CERT_ROOT_CA", dummy_cert_text),
label="Payment processor client certificate root CA",
mst_payment_processor_client_cert_root_ca = PemData.objects.create(
text=os.environ.get("MST_PAYMENT_PROCESSOR_CLIENT_CERT_ROOT_CA", dummy_cert_text),
label="MST payment processor client certificate root CA",
)

sacrt_payment_processor_client_cert = PemData.objects.create(
text=os.environ.get("SACRT_PAYMENT_PROCESSOR_CLIENT_CERT", dummy_cert_text),
label="SacRT payment processor client certificate",
)

sacrt_payment_processor_client_cert_private_key = PemData.objects.create(
text=os.environ.get("SACRT_PAYMENT_PROCESSOR_CLIENT_CERT_PRIVATE_KEY", client_private_key.text),
label="SacRT payment processor client certificate private key",
)

sacrt_payment_processor_client_cert_root_ca = PemData.objects.create(
text=os.environ.get("SACRT_PAYMENT_PROCESSOR_CLIENT_CERT_ROOT_CA", dummy_cert_text),
label="SacRT payment processor client certificate root CA",
)

AuthProvider = app.get_model("core", "AuthProvider")
Expand Down Expand Up @@ -204,18 +219,35 @@ def load_data(app, *args, **kwargs):

PaymentProcessor = app.get_model("core", "PaymentProcessor")

payment_processor = PaymentProcessor.objects.create(
name=os.environ.get("PAYMENT_PROCESSOR_NAME", "Test Payment Processor"),
api_base_url=os.environ.get("PAYMENT_PROCESSOR_API_BASE_URL", "http://server:8000"),
api_access_token_endpoint=os.environ.get("PAYMENT_PROCESSOR_API_ACCESS_TOKEN_ENDPOINT", "access-token"),
api_access_token_request_key=os.environ.get("PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_KEY", "request_access"),
api_access_token_request_val=os.environ.get("PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_VAL", "REQUEST_ACCESS"),
card_tokenize_url=os.environ.get("PAYMENT_PROCESSOR_CARD_TOKENIZE_URL", "http://server:8000/static/tokenize.js"),
card_tokenize_func=os.environ.get("PAYMENT_PROCESSOR_CARD_TOKENIZE_FUNC", "tokenize"),
card_tokenize_env=os.environ.get("PAYMENT_PROCESSOR_CARD_TOKENIZE_ENV", "test"),
client_cert=payment_processor_client_cert,
client_cert_private_key=payment_processor_client_cert_private_key,
client_cert_root_ca=payment_processor_client_cert_root_ca,
mst_payment_processor = PaymentProcessor.objects.create(
name=os.environ.get("MST_PAYMENT_PROCESSOR_NAME", "Test Payment Processor"),
api_base_url=os.environ.get("MST_PAYMENT_PROCESSOR_API_BASE_URL", "http://server:8000"),
api_access_token_endpoint=os.environ.get("MST_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_ENDPOINT", "access-token"),
api_access_token_request_key=os.environ.get("MST_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_KEY", "request_access"),
api_access_token_request_val=os.environ.get("MST_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_VAL", "REQUEST_ACCESS"),
card_tokenize_url=os.environ.get("MST_PAYMENT_PROCESSOR_CARD_TOKENIZE_URL", "http://server:8000/static/tokenize.js"),
card_tokenize_func=os.environ.get("MST_PAYMENT_PROCESSOR_CARD_TOKENIZE_FUNC", "tokenize"),
card_tokenize_env=os.environ.get("MST_PAYMENT_PROCESSOR_CARD_TOKENIZE_ENV", "test"),
client_cert=mst_payment_processor_client_cert,
client_cert_private_key=mst_payment_processor_client_cert_private_key,
client_cert_root_ca=mst_payment_processor_client_cert_root_ca,
customer_endpoint="customer",
customers_endpoint="customers",
group_endpoint="group",
)

sacrt_payment_processor = PaymentProcessor.objects.create(
name=os.environ.get("SACRT_PAYMENT_PROCESSOR_NAME", "Test Payment Processor"),
api_base_url=os.environ.get("SACRT_PAYMENT_PROCESSOR_API_BASE_URL", "http://server:8000"),
api_access_token_endpoint=os.environ.get("SACRT_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_ENDPOINT", "access-token"),
api_access_token_request_key=os.environ.get("SACRT_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_KEY", "request_access"),
api_access_token_request_val=os.environ.get("SACRT_PAYMENT_PROCESSOR_API_ACCESS_TOKEN_REQUEST_VAL", "REQUEST_ACCESS"),
card_tokenize_url=os.environ.get("SACRT_PAYMENT_PROCESSOR_CARD_TOKENIZE_URL", "http://server:8000/static/tokenize.js"),
card_tokenize_func=os.environ.get("SACRT_PAYMENT_PROCESSOR_CARD_TOKENIZE_FUNC", "tokenize"),
card_tokenize_env=os.environ.get("SACRT_PAYMENT_PROCESSOR_CARD_TOKENIZE_ENV", "test"),
client_cert=sacrt_payment_processor_client_cert,
client_cert_private_key=sacrt_payment_processor_client_cert_private_key,
client_cert_root_ca=sacrt_payment_processor_client_cert_root_ca,
customer_endpoint="customer",
customers_endpoint="customers",
group_endpoint="group",
Expand All @@ -240,7 +272,7 @@ def load_data(app, *args, **kwargs):
private_key=client_private_key,
public_key=client_public_key,
jws_signing_alg=os.environ.get("MST_AGENCY_JWS_SIGNING_ALG", "RS256"),
payment_processor=payment_processor,
payment_processor=mst_payment_processor,
eligibility_index_intro=_("eligibility.pages.index.p[0].mst"),
)
mst_agency.eligibility_types.set([mst_senior_type, mst_courtesy_card_type])
Expand All @@ -258,7 +290,7 @@ def load_data(app, *args, **kwargs):
private_key=client_private_key,
public_key=client_public_key,
jws_signing_alg=os.environ.get("SACRT_AGENCY_JWS_SIGNING_ALG", "RS256"),
payment_processor=payment_processor,
payment_processor=sacrt_payment_processor,
eligibility_index_intro=_("eligibility.pages.index.p[0].sacrt"),
)
sacrt_agency.eligibility_types.set([sacrt_senior_type])
Expand Down
2 changes: 1 addition & 1 deletion benefits/enrollment/templates/enrollment/success.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ <h1 class="pb-lg-8 pb-4">{{ page.headline }}</h1>
{% endblock inner-content %}

{% block call-to-action %}
{% if page.buttons|length_is:"1" %}
{% if page.buttons|length == 1 %}
<div class="row d-flex justify-content-lg-center flex-lg-row">
<div class="col-9 col-lg-10 d-flex justify-content-end logout-paragraph">
<p>
Expand Down
10 changes: 7 additions & 3 deletions benefits/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,13 @@ def _filter_empty(ls):
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "benefits", "static")]
# use Manifest Static Files Storage by default
STATICFILES_STORAGE = os.environ.get(
"DJANGO_STATICFILES_STORAGE", "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
)
STORAGES = {
"staticfiles": {
"BACKEND": os.environ.get(
"DJANGO_STATICFILES_STORAGE", "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
)
}
}
STATIC_ROOT = os.path.join(BASE_DIR, "static")

# Logging configuration
Expand Down
4 changes: 4 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:
dockerfile: appcontainer/Dockerfile
image: benefits_client:latest
env_file: .env
platform: linux/amd64
ports:
- "${DJANGO_LOCAL_PORT:-8000}:8000"

Expand All @@ -21,6 +22,7 @@ services:
entrypoint: sleep infinity
depends_on:
- server
platform: linux/amd64
ports:
- "${DJANGO_LOCAL_PORT:-8000}:8000"
volumes:
Expand All @@ -30,6 +32,7 @@ services:
image: benefits_client:dev
entrypoint: mkdocs
command: serve --dev-addr "0.0.0.0:8001"
platform: linux/amd64
ports:
- "8001"
volumes:
Expand All @@ -38,6 +41,7 @@ services:
server:
image: ghcr.io/cal-itp/eligibility-server:dev
env_file: .devcontainer/server/.env.server
platform: linux/amd64
ports:
- "8000"
volumes:
Expand Down
2 changes: 1 addition & 1 deletion docs/use-cases/courtesy-cards.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ flowchart LR
Notes:

- [Eligibility Server documentation](https://docs.calitp.org/eligibility-server/)
- [More details about the Benefits architecture](../deployment/infrastructure/#architecture)
- [More details about the Benefits architecture](../../deployment/infrastructure/#architecture)
- Velocity is the system MST uses to manage Courtesy Cards

## Process
Expand Down
52 changes: 45 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,53 @@
# NOTE: you have to use single-quoted strings in TOML for regular expressions.
# It's the equivalent of r-strings in Python. Multiline strings are treated as
# verbose regular expressions by Black. Use [ ] to denote a significant space
# character.
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"

# Configuration for black
[project]
classifiers = ["Programming Language :: Python :: 3 :: Only"]
description = "Cal-ITP Benefits is an application that enables automated eligibility verification and enrollment for transit benefits onto customers’ existing contactless bank (credit/debit) cards."
dependencies = [
"Authlib==1.2.0",
"Django==4.2",
"django-csp==3.7",
"eligibility-api==2023.01.1",
"requests==2.28.2",
"sentry-sdk==1.19.1",
"six==1.16.0",
]
dynamic = ["version"]
keywords = ["django"]
license = { file = "LICENSE" }
name = "benefits"
readme = "README.md"
requires-python = ">=3.9"

[project.optional-dependencies]
dev = [
"black",
"djlint",
"flake8",
"pre-commit",
]
test = [
"pytest",
"pytest-cov",
"pytest-django",
"pytest-mock",
"pytest-socket",
]

[project.urls]
Code = "https://github.com/cal-itp/benefits"
Documentation = "https://docs.calitp.org/benefits"
Issues = "https://github.com/cal-itp/benefits/issues"

# Configuration for black
[tool.black]
line-length = 127
target-version = ['py310']
include = '\.pyi?$'

# Configuration for djlint

[tool.djlint]
ignore = "H017,H031"
indent = 2
Expand All @@ -22,7 +58,6 @@ preserve_blank_lines = true
use_gitignore = true

# Configuration for pytest

[tool.coverage.run]
omit = [
"benefits/core/migrations/*"
Expand All @@ -33,3 +68,6 @@ DJANGO_SETTINGS_MODULE = "benefits.settings"
markers = [
"request_path: use with session_request to initialize with the given path",
]

[tool.setuptools]
packages = ["benefits"]

0 comments on commit 8eb97d7

Please sign in to comment.