add webhook to docseal
This commit is contained in:
69
enrollments-events/app/app.py
Normal file
69
enrollments-events/app/app.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from aws_lambda_powertools import Logger, Tracer
|
||||||
|
from aws_lambda_powertools.event_handler.api_gateway import (
|
||||||
|
APIGatewayHttpResolver,
|
||||||
|
Response,
|
||||||
|
)
|
||||||
|
from aws_lambda_powertools.logging import correlation_paths
|
||||||
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||||
|
|
||||||
|
from boto3clients import dynamodb_client, s3_client
|
||||||
|
from config import BUCKET_NAME, ENROLLMENT_TABLE
|
||||||
|
from docseal import headers
|
||||||
|
|
||||||
|
logger = Logger(__name__)
|
||||||
|
tracer = Tracer()
|
||||||
|
app = APIGatewayHttpResolver(enable_validation=True)
|
||||||
|
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post('/')
|
||||||
|
@tracer.capture_method
|
||||||
|
def postback():
|
||||||
|
json_body = app.current_event.json_body
|
||||||
|
enrollment_id = json_body['data']['name']
|
||||||
|
combined_document_url = json_body['data'].get('combined_document_url')
|
||||||
|
|
||||||
|
if not combined_document_url:
|
||||||
|
return Response(status_code=HTTPStatus.NO_CONTENT)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(combined_document_url, headers=headers)
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
|
object_key = f'certs/{enrollment_id}.pdf'
|
||||||
|
s3_uri = f's3://{BUCKET_NAME}/{object_key}'
|
||||||
|
|
||||||
|
s3_client.put_object(
|
||||||
|
Bucket=BUCKET_NAME,
|
||||||
|
Key=object_key,
|
||||||
|
Body=r.content,
|
||||||
|
ContentType='application/pdf',
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.debug(f'PDF uploaded successfully to {s3_uri}')
|
||||||
|
except requests.exceptions.RequestException as exc:
|
||||||
|
logger.exception(exc)
|
||||||
|
raise
|
||||||
|
|
||||||
|
dyn.update_item(
|
||||||
|
key=KeyPair(enrollment_id, '0'),
|
||||||
|
cond_expr='attribute_exists(sk)',
|
||||||
|
update_expr='SET cert.s3_uri = :s3_uri',
|
||||||
|
expr_attr_values={':s3_uri': s3_uri},
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(status_code=HTTPStatus.NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
|
||||||
|
@tracer.capture_lambda_handler
|
||||||
|
def lambda_handler(
|
||||||
|
event: dict[str, Any],
|
||||||
|
context: LambdaContext,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
return app.resolve(event, context)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import TypedDict
|
from typing import NotRequired, TypedDict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@@ -8,8 +8,22 @@ headers = {
|
|||||||
'X-Auth-Token': DOCSEAL_KEY,
|
'X-Auth-Token': DOCSEAL_KEY,
|
||||||
}
|
}
|
||||||
|
|
||||||
Submitter = TypedDict('Submitter', {'role': str, 'name': str, 'email': str})
|
Submitter = TypedDict(
|
||||||
EmailMessage = TypedDict('EmailMessage', {'subject': str, 'body': str})
|
'Submitter',
|
||||||
|
{
|
||||||
|
'role': str,
|
||||||
|
'name': str,
|
||||||
|
'email': str,
|
||||||
|
'external_id': NotRequired[str],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
EmailMessage = TypedDict(
|
||||||
|
'EmailMessage',
|
||||||
|
{
|
||||||
|
'subject': str,
|
||||||
|
'body': str,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_submission_from_pdf(
|
def create_submission_from_pdf(
|
||||||
|
|||||||
@@ -45,9 +45,10 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
|||||||
},
|
},
|
||||||
submitters=[
|
submitters=[
|
||||||
{
|
{
|
||||||
'role': 'Aluno',
|
'role': 'First Party',
|
||||||
'name': user['name'],
|
'name': user['name'],
|
||||||
'email': user['email'],
|
'email': user['email'],
|
||||||
|
'external_id': user['id'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,6 +50,39 @@ Resources:
|
|||||||
Properties:
|
Properties:
|
||||||
RetentionInDays: 90
|
RetentionInDays: 90
|
||||||
|
|
||||||
|
HttpLog:
|
||||||
|
Type: AWS::Logs::LogGroup
|
||||||
|
Properties:
|
||||||
|
RetentionInDays: 90
|
||||||
|
|
||||||
|
HttpApi:
|
||||||
|
Type: AWS::Serverless::HttpApi
|
||||||
|
Properties:
|
||||||
|
CorsConfiguration:
|
||||||
|
AllowOrigins: ["*"]
|
||||||
|
AllowMethods: [POST, OPTIONS]
|
||||||
|
AllowHeaders: [Content-Type, X-Requested-With]
|
||||||
|
|
||||||
|
HttpApiFunction:
|
||||||
|
Type: AWS::Serverless::Function
|
||||||
|
Properties:
|
||||||
|
Handler: app.lambda_handler
|
||||||
|
Timeout: 12
|
||||||
|
LoggingConfig:
|
||||||
|
LogGroup: !Ref HttpLog
|
||||||
|
Policies:
|
||||||
|
- DynamoDBWritePolicy:
|
||||||
|
TableName: !Ref EnrollmentTable
|
||||||
|
- S3WritePolicy:
|
||||||
|
BucketName: !Ref BucketName
|
||||||
|
Events:
|
||||||
|
Post:
|
||||||
|
Type: HttpApi
|
||||||
|
Properties:
|
||||||
|
Path: /
|
||||||
|
Method: POST
|
||||||
|
ApiId: !Ref HttpApi
|
||||||
|
|
||||||
EventSetSubscriptionCoveredFunction:
|
EventSetSubscriptionCoveredFunction:
|
||||||
Type: AWS::Serverless::Function
|
Type: AWS::Serverless::Function
|
||||||
Properties:
|
Properties:
|
||||||
@@ -422,3 +455,13 @@ Resources:
|
|||||||
- prefix: CERT_REPORTING#ORG
|
- prefix: CERT_REPORTING#ORG
|
||||||
sk:
|
sk:
|
||||||
- suffix: SCHEDULE#SEND_REPORT_EMAIL
|
- suffix: SCHEDULE#SEND_REPORT_EMAIL
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
HttpApiUrl:
|
||||||
|
Description: URL of your API endpoint
|
||||||
|
Value:
|
||||||
|
Fn::Sub: "https://${HttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}"
|
||||||
|
HttpApiId:
|
||||||
|
Description: Api ID of HttpApi
|
||||||
|
Value:
|
||||||
|
Ref: HttpApi
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import base64
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from http import HTTPMethod
|
||||||
|
|
||||||
import jsonlines
|
import jsonlines
|
||||||
import pytest
|
import pytest
|
||||||
@@ -17,6 +20,7 @@ def pytest_configure():
|
|||||||
os.environ['DOCSEAL_KEY'] = 'gUWhWtYBgTaP8fc1q5GZ6JuUHaZzMgZna6KFBHz3Gzk'
|
os.environ['DOCSEAL_KEY'] = 'gUWhWtYBgTaP8fc1q5GZ6JuUHaZzMgZna6KFBHz3Gzk'
|
||||||
os.environ['USER_TABLE'] = PYTEST_TABLE_NAME
|
os.environ['USER_TABLE'] = PYTEST_TABLE_NAME
|
||||||
os.environ['COURSE_TABLE'] = PYTEST_TABLE_NAME
|
os.environ['COURSE_TABLE'] = PYTEST_TABLE_NAME
|
||||||
|
os.environ['ENROLLMENT_TABLE'] = PYTEST_TABLE_NAME
|
||||||
os.environ['ORDER_TABLE'] = PYTEST_TABLE_NAME
|
os.environ['ORDER_TABLE'] = PYTEST_TABLE_NAME
|
||||||
os.environ['ENROLLMENT_TABLE'] = PYTEST_TABLE_NAME
|
os.environ['ENROLLMENT_TABLE'] = PYTEST_TABLE_NAME
|
||||||
os.environ['BUCKET_NAME'] = 'saladeaula.digital'
|
os.environ['BUCKET_NAME'] = 'saladeaula.digital'
|
||||||
@@ -36,6 +40,78 @@ def lambda_context() -> LambdaContext:
|
|||||||
return LambdaContext()
|
return LambdaContext()
|
||||||
|
|
||||||
|
|
||||||
|
class HttpApiProxy:
|
||||||
|
def __call__(
|
||||||
|
self,
|
||||||
|
raw_path: str,
|
||||||
|
method: str = HTTPMethod.GET,
|
||||||
|
body: dict = {},
|
||||||
|
*,
|
||||||
|
headers: dict = {},
|
||||||
|
auth_flow_type: str = 'USER_AUTH',
|
||||||
|
queryStringParameters: dict = {},
|
||||||
|
**kwargs,
|
||||||
|
) -> dict:
|
||||||
|
return {
|
||||||
|
'version': '2.0',
|
||||||
|
'routeKey': '$default',
|
||||||
|
'rawPath': raw_path,
|
||||||
|
'rawQueryString': 'parameter1=value1¶meter1=value2¶meter2=value',
|
||||||
|
'cookies': ['cookie1', 'cookie2'],
|
||||||
|
'headers': headers,
|
||||||
|
'queryStringParameters': queryStringParameters,
|
||||||
|
'requestContext': {
|
||||||
|
'accountId': '123456789012',
|
||||||
|
'apiId': 'api-id',
|
||||||
|
'authorizer': {
|
||||||
|
'lambda': {
|
||||||
|
'user': {
|
||||||
|
'name': 'Sérgio R Siqueira',
|
||||||
|
'email': 'sergio@somosbeta.com.br',
|
||||||
|
'email_verified': 'true',
|
||||||
|
'custom:user_id': '5OxmMjL-ujoR5IMGegQz',
|
||||||
|
'sub': 'c4f30dbd-083e-4b84-aa50-c31afe9b9c01',
|
||||||
|
},
|
||||||
|
'auth_flow_type': auth_flow_type,
|
||||||
|
},
|
||||||
|
'jwt': {
|
||||||
|
'claims': {'claim1': 'value1', 'claim2': 'value2'},
|
||||||
|
'scopes': ['scope1', 'scope2'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'domainName': 'id.execute-api.us-east-1.amazonaws.com',
|
||||||
|
'domainPrefix': 'id',
|
||||||
|
'http': {
|
||||||
|
'method': str(method),
|
||||||
|
'path': raw_path,
|
||||||
|
'protocol': 'HTTP/1.1',
|
||||||
|
'sourceIp': '192.168.0.1/32',
|
||||||
|
'userAgent': 'agent',
|
||||||
|
},
|
||||||
|
'requestId': 'id',
|
||||||
|
'routeKey': '$default',
|
||||||
|
'stage': '$default',
|
||||||
|
'time': '12/Mar/2020:19:03:58 +0000',
|
||||||
|
'timeEpoch': 1583348638390,
|
||||||
|
},
|
||||||
|
'body': _base64_dict(body),
|
||||||
|
'pathParameters': {'parameter1': 'value1'},
|
||||||
|
'isBase64Encoded': True,
|
||||||
|
'stageVariables': {'stageVariable1': 'value1', 'stageVariable2': 'value2'},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _base64_dict(obj: dict = {}) -> str | None:
|
||||||
|
if not obj:
|
||||||
|
return None
|
||||||
|
return base64.b64encode(json.dumps(obj).encode()).decode()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def http_api_proxy():
|
||||||
|
return HttpApiProxy()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def dynamodb_client():
|
def dynamodb_client():
|
||||||
from boto3clients import dynamodb_client as client
|
from boto3clients import dynamodb_client as client
|
||||||
@@ -80,3 +156,10 @@ def seeds(dynamodb_client):
|
|||||||
TableName=PYTEST_TABLE_NAME,
|
TableName=PYTEST_TABLE_NAME,
|
||||||
Item=serialize(line),
|
Item=serialize(line),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def app():
|
||||||
|
import app
|
||||||
|
|
||||||
|
return app
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import app.events.send_reminder_emails as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||||
|
|
||||||
|
import events.send_reminder_emails as app
|
||||||
|
|
||||||
|
|
||||||
def test_reminder_access_period_before_30_days(
|
def test_reminder_access_period_before_30_days(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import app.events.send_reminder_emails as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
|
|
||||||
|
import events.send_reminder_emails as app
|
||||||
|
|
||||||
|
|
||||||
def test_reminder_cert_expiration_before_30_days(
|
def test_reminder_cert_expiration_before_30_days(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import app.events.send_reminder_emails as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
|
|
||||||
|
import events.send_reminder_emails as app
|
||||||
|
|
||||||
|
|
||||||
def test_reminder_no_access_after_3_days(
|
def test_reminder_no_access_after_3_days(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import app.events.send_reminder_emails as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
|
|
||||||
|
import events.send_reminder_emails as app
|
||||||
|
|
||||||
|
|
||||||
def test_reminder_no_activity_after_7_days(
|
def test_reminder_no_activity_after_7_days(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
import app.events.reporting.append_cert as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dateutils import now
|
from layercake.dateutils import now
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
@@ -9,6 +8,8 @@ from layercake.dynamodb import (
|
|||||||
TransactKey,
|
TransactKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.reporting.append_cert as app
|
||||||
|
|
||||||
|
|
||||||
def test_append_cert(
|
def test_append_cert(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import app.events.reporting.send_report_email as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
KeyPair,
|
KeyPair,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.reporting.send_report_email as app
|
||||||
|
|
||||||
|
|
||||||
def test_send_report_email(
|
def test_send_report_email(
|
||||||
monkeypatch,
|
monkeypatch,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import app.events.stopgap.patch_course_metadata as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
SortKey,
|
KeyPair,
|
||||||
TransactKey,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.stopgap.patch_course_metadata as app
|
||||||
|
|
||||||
|
|
||||||
def test_enroll(
|
def test_enroll(
|
||||||
seeds,
|
seeds,
|
||||||
@@ -27,10 +27,8 @@ def test_enroll(
|
|||||||
}
|
}
|
||||||
assert app.lambda_handler(event, lambda_context) # type: ignore
|
assert app.lambda_handler(event, lambda_context) # type: ignore
|
||||||
|
|
||||||
result = dynamodb_persistence_layer.collection.get_items(
|
r = dynamodb_persistence_layer.collection.get_item(
|
||||||
TransactKey('47ZxxcVBjvhDS5TE98tpfQ')
|
KeyPair('47ZxxcVBjvhDS5TE98tpfQ', '0')
|
||||||
+ SortKey('0')
|
|
||||||
+ SortKey('METADATA#DEDUPLICATION_WINDOW')
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert 'METADATA#DEDUPLICATION_WINDOW' in result
|
assert 'access_expires_at' in r
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import app.events.allocate_slots as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey
|
from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey
|
||||||
|
|
||||||
|
import events.allocate_slots as app
|
||||||
|
|
||||||
|
|
||||||
def test_allocate_slots(
|
def test_allocate_slots(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ def test_ask_to_sign(
|
|||||||
's3_uri': 's3://saladeaula.digital/certs/samples/nr11-operador-de-munck.pdf'
|
's3_uri': 's3://saladeaula.digital/certs/samples/nr11-operador-de-munck.pdf'
|
||||||
},
|
},
|
||||||
'user': {
|
'user': {
|
||||||
|
'id': '5OxmMjL-ujoR5IMGegQz',
|
||||||
'name': 'Sérgio R Siqueira',
|
'name': 'Sérgio R Siqueira',
|
||||||
'email': 'sergio@somosbeta.com.br',
|
'email': 'sergio@somosbeta.com.br',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import app.events.enroll as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, PartitionKey
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, PartitionKey
|
||||||
|
|
||||||
|
import events.enroll as app
|
||||||
|
|
||||||
|
|
||||||
def test_enroll(
|
def test_enroll(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import app.events.reenroll_if_failed as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||||
|
|
||||||
|
import events.reenroll_if_failed as app
|
||||||
|
|
||||||
|
|
||||||
def test_reenroll_custom_dedup_window(
|
def test_reenroll_custom_dedup_window(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import app.events.schedule_reminders as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
PartitionKey,
|
PartitionKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.schedule_reminders as app
|
||||||
|
|
||||||
|
|
||||||
def test_schedule_reminders(
|
def test_schedule_reminders(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import app.events.set_access_expired as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
@@ -6,6 +5,8 @@ from layercake.dynamodb import (
|
|||||||
TransactKey,
|
TransactKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.set_access_expired as app
|
||||||
|
|
||||||
|
|
||||||
def test_set_access_expired(
|
def test_set_access_expired(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import app.events.set_cert_expired as app
|
|
||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
@@ -6,6 +5,8 @@ from layercake.dynamodb import (
|
|||||||
TransactKey,
|
TransactKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import events.set_cert_expired as app
|
||||||
|
|
||||||
|
|
||||||
def test_set_cert_expired(
|
def test_set_cert_expired(
|
||||||
seeds,
|
seeds,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Enrollment
|
// Enrollment
|
||||||
{"id": "6437a282-6fe8-4e4d-9eb0-da1007238007", "sk": "0", "status": "IN_PROGRESS", "progress": 10}
|
{"id": "6437a282-6fe8-4e4d-9eb0-da1007238007", "sk": "0", "status": "IN_PROGRESS", "progress": 10}
|
||||||
{"id": "845fe390-e3c3-4514-97f8-c42de0566cf0", "sk": "0", "status": "COMPLETED", "progress": 100}
|
{"id": "845fe390-e3c3-4514-97f8-c42de0566cf0", "sk": "0", "status": "COMPLETED", "progress": 100, "cert": {"s3_uri": "s3://saladeaula.digital/certs/samples/nr11-operador-de-munck.pdf", "issued_at": "2025-08-24T01:44:42.703012-03:06"}}
|
||||||
|
|
||||||
{"id": "1ee108ae-67d4-4545-bf6d-4e641cdaa4e0", "sk": "0", "status": "COMPLETED", "score": 100, "course": {"id": "123", "name": "CIPA Grau de Risco 1"}, "user": {"name": "Kurt Cobain"}, "cert": {"s3_uri": "s3://saladeaula.digital/issuedcerts/1ee108ae-67d4-4545-bf6d-4e641cdaa4e0.pdf"}}
|
{"id": "1ee108ae-67d4-4545-bf6d-4e641cdaa4e0", "sk": "0", "status": "COMPLETED", "score": 100, "course": {"id": "123", "name": "CIPA Grau de Risco 1"}, "user": {"name": "Kurt Cobain"}, "cert": {"s3_uri": "s3://saladeaula.digital/issuedcerts/1ee108ae-67d4-4545-bf6d-4e641cdaa4e0.pdf"}}
|
||||||
{"id": "1ee108ae-67d4-4545-bf6d-4e641cdaa4e0", "sk": "STARTED", "started_at": "2025-08-24T01:44:42.703012-03:06"}
|
{"id": "1ee108ae-67d4-4545-bf6d-4e641cdaa4e0", "sk": "STARTED", "started_at": "2025-08-24T01:44:42.703012-03:06"}
|
||||||
|
|||||||
38
enrollments-events/tests/test_app.py
Normal file
38
enrollments-events/tests/test_app.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
from http import HTTPMethod, HTTPStatus
|
||||||
|
|
||||||
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||||
|
|
||||||
|
from .conftest import HttpApiProxy, LambdaContext
|
||||||
|
|
||||||
|
enrollment_id = '845fe390-e3c3-4514-97f8-c42de0566cf0'
|
||||||
|
body = {
|
||||||
|
'data': {
|
||||||
|
'name': enrollment_id,
|
||||||
|
'slug': 'jzNV3ZrF6T16tX',
|
||||||
|
'combined_document_url': 'https://docs.eduseg.com.br/file/WyI3MGVhNGQwYS02YTE5LTQyYzItODgyNy1iZTc0Zjc2ZTlkNmUiLCJibG9iIiwxNzYyMjEwMjg2XQ--72caad853fdc1c64c5321368c7d883828be0b859ed39689355bac9dffe71b8e2/e249c51b-3e68-42eb-bb4b-20659263ce1c.pdf',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_postback(
|
||||||
|
app,
|
||||||
|
seeds,
|
||||||
|
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||||
|
http_api_proxy: HttpApiProxy,
|
||||||
|
lambda_context: LambdaContext,
|
||||||
|
):
|
||||||
|
# This data was added from seeds
|
||||||
|
r = app.lambda_handler(
|
||||||
|
http_api_proxy(
|
||||||
|
raw_path='/',
|
||||||
|
method=HTTPMethod.POST,
|
||||||
|
body=body,
|
||||||
|
),
|
||||||
|
lambda_context,
|
||||||
|
)
|
||||||
|
assert r['statusCode'] == HTTPStatus.NO_CONTENT
|
||||||
|
|
||||||
|
r = dynamodb_persistence_layer.get_item(
|
||||||
|
KeyPair('845fe390-e3c3-4514-97f8-c42de0566cf0', '0')
|
||||||
|
)
|
||||||
|
print(r)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import base64
|
import base64
|
||||||
import uuid
|
import uuid
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from docseal import create_submission_from_pdf
|
from docseal import create_submission_from_pdf
|
||||||
|
|
||||||
@@ -13,10 +13,12 @@ Seu certificado já está pronto e aguardando apenas a sua assinatura digital.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_create_submission_from_pdf():
|
def Response(*args, **kwargs):
|
||||||
r = MagicMock()
|
return type('Response', (), {'raise_for_status': object})
|
||||||
|
|
||||||
with patch('docseal.requests.post', r):
|
|
||||||
|
def test_create_submission_from_pdf():
|
||||||
|
with patch('docseal.requests.post', Response):
|
||||||
with open('tests/sample.pdf', 'rb') as f:
|
with open('tests/sample.pdf', 'rb') as f:
|
||||||
file = base64.b64encode(f.read())
|
file = base64.b64encode(f.read())
|
||||||
create_submission_from_pdf(
|
create_submission_from_pdf(
|
||||||
|
|||||||
Reference in New Issue
Block a user