Skip to content

Commit

Permalink
fix new vs reuse sbc account flow
Browse files Browse the repository at this point in the history
  • Loading branch information
turb0c0w committed May 24, 2024
1 parent f8ae000 commit b3bb2ab
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 36 deletions.
30 changes: 30 additions & 0 deletions strr-api/migrations/versions/20240524_894fe4847de6_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""empty message
Revision ID: 894fe4847de6
Revises: 3d7b4953b1ee
Create Date: 2024-05-24 09:34:10.209903
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '894fe4847de6'
down_revision = '3d7b4953b1ee'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('registrations', schema=None) as batch_op:
batch_op.add_column(sa.Column('sbc_account_id', sa.INTEGER(), autoincrement=False, nullable=True))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('registrations', schema=None) as batch_op:
batch_op.drop_column('sbc_account_id')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions strr-api/src/strr_api/models/rental.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class Registration(db.Model):
__tablename__ = "registrations"

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
sbc_account_id = db.Column(db.Integer, nullable=True)
rental_property_id = db.Column(db.Integer, db.ForeignKey("rental_properties.id"), nullable=False)
submission_date = db.Column(db.DateTime, default=datetime.now, nullable=False)
updated_date = db.Column(db.DateTime, default=datetime.now, nullable=False)
Expand Down
29 changes: 26 additions & 3 deletions strr-api/src/strr_api/requests/RegistrationRequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,36 @@ def __init__(self, street, city, region, postalCode, country, streetAdditional=N
self.postalCode = postalCode
self.country = country

def to_dict(self):
"""Convert object to dictionary for json serialization."""
return {
key: value
for key, value in {
"street": self.street,
"streetAdditional": self.streetAdditional,
"city": self.city,
"region": self.region,
"postalCode": self.postalCode,
"country": self.country,
}.items()
if value is not None
}


class SelectedAccount:
"""SelectedAccount payload object."""

def __init__(self, name, mailingAddress):
self.name = name
self.mailingAddress = SBCMailingAddress(**mailingAddress)
def __init__(self, sbc_account_id=None, name=None, mailingAddress=None):
self.sbc_account_id = None
self.name = None
self.mailingAddress = None

if sbc_account_id:
self.sbc_account_id = sbc_account_id
if name:
self.name = name
if mailingAddress:
self.mailingAddress = SBCMailingAddress(**mailingAddress)


class Registration:
Expand Down
28 changes: 19 additions & 9 deletions strr-api/src/strr_api/resources/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from http import HTTPStatus

from flasgger import swag_from
from flask import Blueprint, jsonify, request
from flask import Blueprint, g, jsonify, request
from flask_cors import cross_origin

from strr_api.common.auth import jwt
Expand Down Expand Up @@ -125,15 +125,23 @@ def create_account():
registration_request = RegistrationRequest(**json_input)
selected_account = registration_request.selectedAccount

# TODO: link SBC account to User account
AuthService.create_user_account(token, selected_account.name, selected_account.mailingAddress)
# SBC Account lookup or creation
sbc_account_id = None
if selected_account.sbc_account_id:
sbc_account_id = selected_account.sbc_account_id
else:
new_account = AuthService.create_user_account(
token, selected_account.name, selected_account.mailingAddress.to_dict()
)
sbc_account_id = new_account.get("id")

# DO POSTAL CODE VALIDATION IF COUNTRY IS CANADA
selected_account.mailingAddress.postalCode = validate_and_format_canadian_postal_code(
selected_account.mailingAddress.country,
selected_account.mailingAddress.region,
selected_account.mailingAddress.postalCode,
)
if selected_account.mailingAddress:
selected_account.mailingAddress.postalCode = validate_and_format_canadian_postal_code(
selected_account.mailingAddress.country,
selected_account.mailingAddress.region,
selected_account.mailingAddress.postalCode,
)

registration_request.registration.unitAddress.postalCode = validate_and_format_canadian_postal_code(
registration_request.registration.unitAddress.country,
Expand Down Expand Up @@ -164,7 +172,9 @@ def create_account():
)
)

registration = RegistrationService.save_registration(token, registration_request.registration)
registration = RegistrationService.save_registration(
g.jwt_oidc_token_info, sbc_account_id, registration_request.registration
)
return jsonify(Registration.from_db(registration).model_dump(mode="json")), HTTPStatus.CREATED
except ValidationException as auth_exception:
return exception_response(auth_exception)
Expand Down
5 changes: 2 additions & 3 deletions strr-api/src/strr_api/resources/registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from http import HTTPStatus

from flasgger import swag_from
from flask import Blueprint, jsonify
from flask import Blueprint, g, jsonify
from flask_cors import cross_origin

from strr_api.common.auth import jwt
Expand Down Expand Up @@ -70,8 +70,7 @@ def get_registrations():
"""

try:
token = jwt.get_token_auth_header()
registrations = RegistrationService.list_registrations(token)
registrations = RegistrationService.list_registrations(g.jwt_oidc_token_info)
return (
jsonify([Registration.from_db(registration).model_dump(mode="json") for registration in registrations]),
HTTPStatus.OK,
Expand Down
11 changes: 3 additions & 8 deletions strr-api/src/strr_api/responses/RegistrationResponse.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ class SBCMailingAddress(BaseModel):
country: str


class SelectedAccount(BaseModel):
"""SelectedAccount response object."""

name: str
mailingAddress: SBCMailingAddress


class ListingDetails(BaseModel):
"""ListingDetails response object."""

Expand Down Expand Up @@ -78,7 +71,7 @@ class ContactDetails(BaseModel):
phoneNumber: str
extension: Optional[str] = None
faxNumber: Optional[str] = None
emailAddress: str
emailAddress: Optional[str] = None


class Contact(BaseModel):
Expand All @@ -94,6 +87,7 @@ class Registration(BaseModel):
"""Registration response object."""

id: int
sbc_account_id: Optional[int] = None
submissionDate: datetime
updatedDate: datetime
status: str
Expand All @@ -108,6 +102,7 @@ def from_db(cls, source: models.Registration):
"""Return a Registration object from a database model."""
return cls(
id=source.id,
sbc_account_id=source.sbc_account_id,
submissionDate=source.submission_date,
updatedDate=source.updated_date,
status=source.status.name,
Expand Down
17 changes: 15 additions & 2 deletions strr-api/src/strr_api/schemas/schemas/registration.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@
"properties": {
"selectedAccount": {
"type": "object",
"sbc_account_id": {
"type": "integer"
},
"name": {
"description": "Account Name",
"type": "string"
Expand Down Expand Up @@ -157,8 +160,18 @@
}
}
},
"required": [
"name"
"oneOf": [
{
"required": [
"sbc_account_id"
]
},
{
"required": [
"name",
"mailingAddress"
]
}
]
},
"registration": {
Expand Down
12 changes: 7 additions & 5 deletions strr-api/src/strr_api/services/registration_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ class RegistrationService:
"""Service to save and load regristration details from the database."""

@classmethod
def save_registration(cls, token, registration_request: requests.Registration):
def save_registration(cls, jwt_oidc_token_info, sbc_account_id, registration_request: requests.Registration):
"""Save STRR property registration to database."""

# TODO: FUTURE SPRINT - handle the other cases where jwt doesn't have the info
user = models.User.get_or_create_user_by_jwt(token)
user.preferredname = (registration_request.primaryContact.details.preferredName,)
user = models.User.get_or_create_user_by_jwt(jwt_oidc_token_info)
user.email = registration_request.primaryContact.details.emailAddress
user.preferredname = registration_request.primaryContact.details.preferredName
user.phone_extension = registration_request.primaryContact.details.extension
user.fax_number = registration_request.primaryContact.details.faxNumber
user.phone_number = registration_request.primaryContact.details.phoneNumber
Expand Down Expand Up @@ -100,6 +101,7 @@ def save_registration(cls, token, registration_request: requests.Registration):
db.session.refresh(property_manager)

registration = models.Registration(
sbc_account_id=sbc_account_id,
status=RegistrationStatus.PENDING,
rental_property=models.RentalProperty(
property_manager_id=property_manager.id,
Expand Down Expand Up @@ -128,9 +130,9 @@ def save_registration(cls, token, registration_request: requests.Registration):
return registration

@classmethod
def list_registrations(cls, token):
def list_registrations(cls, jwt_oidc_token_info):
"""List all registrations for current user."""
user = models.User.find_by_jwt_token(token)
user = models.User.find_by_jwt_token(jwt_oidc_token_info)
return (
models.Registration.query.join(
models.PropertyManager, models.PropertyManager.id == models.Registration.rental_property_id
Expand Down
File renamed without changes.
73 changes: 73 additions & 0 deletions strr-api/tests/mocks/json/registration_use_sbc_account.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"selectedAccount": {
"sbc_account_id": 3299
},
"registration": {
"primaryContact": {
"name": {
"firstName": "The",
"middleName": "First",
"lastName": "Guy"
},
"dateOfBirth": "1986-10-23",
"details": {
"preferredName": "Mickey",
"phoneNumber": "604-999-9999",
"extension": "x64",
"faxNumber": "604-777-7777",
"emailAddress": "[email protected]"
},
"mailingAddress": {
"country": "CA",
"address": "12766 227st",
"addressLineTwo": "",
"city": "MAPLE RIDGE",
"province": "BC",
"postalCode": "V2X 6K6"
}
},
"secondaryContact": {
"name": {
"firstName": "The",
"middleName": "Other",
"lastName": "Guy"
},
"dateOfBirth": "1986-10-23",
"details": {
"preferredName": "Mouse",
"phoneNumber": "604-888-8888",
"extension": "",
"faxNumber": "",
"emailAddress": "[email protected]"
},
"mailingAddress": {
"country": "CA",
"address": "12766 227st",
"addressLineTwo": "",
"city": "MAPLE RIDGE",
"province": "BC",
"postalCode": "V2X 6K6"
}
},
"unitDetails": {
"parcelIdentifier": "000-460-991",
"businessLicense": "",
"propertyType": "PRIMARY",
"ownershipType": "OWN"
},
"unitAddress": {
"nickname": "My Rental Property",
"country": "CA",
"address": "12166 GREENWELL ST MAPLE RIDGE",
"addressLineTwo": "",
"city": "MAPLE RIDGE",
"province": "BC",
"postalCode": "V2X 7N1"
},
"listingDetails": [
{
"url": "https://www.airbnb.ca/rooms/26359027"
}
]
}
}
5 changes: 4 additions & 1 deletion strr-api/tests/unit/resources/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from http import HTTPStatus
from unittest.mock import patch

from flask import g

from tests.unit.utils.mocks import (
empty_json,
fake_get_token_auth_header,
Expand All @@ -11,7 +13,7 @@
no_op,
)

REGISTRATION = "registration"
REGISTRATION = "registration_new_sbc_account"
MOCK_ACCOUNT_REQUEST = os.path.join(
os.path.dirname(os.path.realpath(__file__)), f"../../mocks/json/{REGISTRATION}.json"
)
Expand Down Expand Up @@ -45,6 +47,7 @@ def test_me_401(client):
@patch("flask_jwt_oidc.JwtManager._validate_token", new=no_op)
def test_create_account_201(client):
with open(MOCK_ACCOUNT_REQUEST) as f:
g.jwt_oidc_token_info = None
data = json.load(f)
rv = client.post("/account", json=data)
assert rv.status_code == HTTPStatus.CREATED
Expand Down
3 changes: 3 additions & 0 deletions strr-api/tests/unit/resources/test_registrations.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from http import HTTPStatus
from unittest.mock import patch

from flask import g

from tests.unit.utils.mocks import fake_get_token_auth_header, fake_user_from_token, no_op


@patch("strr_api.models.user.User.find_by_jwt_token", new=fake_user_from_token)
@patch("flask_jwt_oidc.JwtManager.get_token_auth_header", new=fake_get_token_auth_header)
@patch("flask_jwt_oidc.JwtManager._validate_token", new=no_op)
def test_registrations_200(client):
g.jwt_oidc_token_info = None
rv = client.get("/registrations")
assert rv.status_code == HTTPStatus.OK

Expand Down
Loading

0 comments on commit b3bb2ab

Please sign in to comment.