diff --git a/api/account/tests/features/steps/new_account.py b/api/account/tests/features/steps/new_account.py index b593d9f3..e0bd83ab 100644 --- a/api/account/tests/features/steps/new_account.py +++ b/api/account/tests/features/steps/new_account.py @@ -28,7 +28,7 @@ def build_new_account_request(context): @given('user opts out of membership') def add_maybe_later_membership(context): context.new_account_request['support'].update( - membership='Maybe Later', + membership=None, paymentMethod=None, paymentAccountId=None ) diff --git a/api/account/tests/features/steps/update_membership.py b/api/account/tests/features/steps/update_membership.py index f3e12b2e..58345559 100644 --- a/api/account/tests/features/steps/update_membership.py +++ b/api/account/tests/features/steps/update_membership.py @@ -1,11 +1,10 @@ import json -from datetime import date from behave import given, when, then -from hamcrest import assert_that, equal_to, starts_with +from hamcrest import assert_that, equal_to, starts_with, none from selene.api.testing import generate_access_token, generate_refresh_token -from selene.data.account import AccountRepository, Account, AccountAgreement, PRIVACY_POLICY +from selene.data.account import AccountRepository from selene.util.db import get_db_connection new_account_request = dict( @@ -15,40 +14,45 @@ new_account_request = dict( login=dict( federatedEmail=None, userEnteredEmail='test@mycroft.ai', - password='12345678' + password='test' ), support=dict( openDataset=True, - membership='Maybe Later', - paymentMethod=None, - paymentAccountId=None + membership=None ) ) +free_membership = { + 'support': None +} + monthly_membership = { - 'support': { - 'membership': 'Monthly Membership', - 'payment_method': 'Stripe', - 'payment_token': 'tok_visa' - } + 'support': { + 'membership': 'Monthly Membership', + 'payment_method': 'Stripe', + 'payment_token': 'tok_visa' } +} + +yearly_membership = { + 'support': { + 'membership': 'Yearly Membership', + 'payment_method': 'Stripe', + 'payment_token': 'tok_visa' + } +} @given('a user with a free account') -def create_account(context): - context.account = Account( - email_address='test@mycroft.ai', - username='test', - refresh_tokens=[], - membership=None, - agreements=[ - AccountAgreement(type=PRIVACY_POLICY, accept_date=date.today()) - ] +def create_account_free_account(context): + context.client.post( + '/api/account', + data=json.dumps(new_account_request), + content_type='application_json' ) with get_db_connection(context.client_config['DB_CONNECTION_POOL']) as db: - acct_repository = AccountRepository(db) - account_id = acct_repository.add(context.account, 'foo') - context.account.id = account_id + account = AccountRepository(db).get_account_by_email(new_account_request['login']['userEnteredEmail']) + context.account = account generate_access_token(context) generate_refresh_token(context) @@ -73,3 +77,49 @@ def monthly_account(context): account = context.response_account assert_that(account.membership.type, equal_to(monthly_membership['support']['membership'])) assert_that(account.membership.payment_account_id, starts_with('cus')) + + +@given('a user with a monthly membership') +def create_monthly_account(context): + new_account_request['membership'] = monthly_membership + context.client.post( + '/api/account', + data=json.dumps(new_account_request), + content_type='application_json' + ) + with get_db_connection(context.client_config['DB_CONNECTION_POOL']) as db: + account = AccountRepository(db).get_account_by_email(new_account_request['login']['userEnteredEmail']) + context.account = account + generate_access_token(context) + generate_refresh_token(context) + + +@when('the membership is cancelled') +def cancel_membership(context): + context.client.patch( + '/api/account', + data=json.dumps(free_membership), + content_type='application_json' + ) + + +@then('the account should have no membership') +def free_account(context): + account = context.response_account + assert_that(account.membership, none()) + + +@when('the membership is changed to yearly') +def change_to_yearly_account(context): + context.client.patch( + '/api/account', + data=json.dumps(yearly_membership), + content_type='application_json' + ) + + +@then('the account should have a yearly membership') +def yearly_account(context): + account = context.response_account + assert_that(account.membership.type, equal_to(yearly_membership['support']['membership'])) + assert_that(account.membership.payment_account_id, starts_with('cus')) diff --git a/api/account/tests/features/update_membership.feature b/api/account/tests/features/update_membership.feature index f799c541..fd414175 100644 --- a/api/account/tests/features/update_membership.feature +++ b/api/account/tests/features/update_membership.feature @@ -4,4 +4,16 @@ Feature: Test the API call to update a membership Given a user with a free account When a monthly membership is added And the account is requested - Then the account should have a monthly membership \ No newline at end of file + Then the account should have a monthly membership + + Scenario: user opts out monthly membership + Given a user with a monthly membership + When the membership is cancelled + And the account is requested + Then the account should have no membership + + Scenario: user changes from a monthly membership to yearly membership + Given a user with a monthly membership + When the membership is changed to yearly + And the account is requested + Then the account should have a yearly membership \ No newline at end of file diff --git a/shared/selene/api/endpoints/account.py b/shared/selene/api/endpoints/account.py index 57d0f199..1b27595b 100644 --- a/shared/selene/api/endpoints/account.py +++ b/shared/selene/api/endpoints/account.py @@ -23,7 +23,6 @@ from ..base_endpoint import SeleneEndpoint MONTHLY_MEMBERSHIP = 'Monthly Membership' YEARLY_MEMBERSHIP = 'Yearly Membership' -NO_MEMBERSHIP = 'Maybe Later' STRIPE_PAYMENT = 'Stripe' stripe.api_key = os.environ['STRIPE_PRIVATE_KEY'] @@ -57,8 +56,7 @@ class Login(Model): class Support(Model): open_dataset = BooleanType(required=True) membership = StringType( - required=True, - choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP) + choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP) ) payment_method = StringType(choices=[STRIPE_PAYMENT]) payment_token = StringType() @@ -67,7 +65,7 @@ class Support(Model): class AddMembership(Model): membership = StringType( required=True, - choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP) + choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP) ) payment_method = StringType(required=True, choices=[STRIPE_PAYMENT]) payment_token = StringType(required=True) @@ -76,7 +74,7 @@ class AddMembership(Model): class UpdateMembership(Model): membership = StringType( required=True, - choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP) + choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP) ) @@ -108,7 +106,7 @@ class AccountEndpoint(SeleneEndpoint): agreement_date = self._format_agreement_date(agreement) agreement['accept_date'] = agreement_date if response_data['membership'] is None: - response_data['membership'] = dict(type=NO_MEMBERSHIP) + response_data['membership'] = None else: membership_duration = self._format_membership_duration(response_data) response_data['membership']['duration'] = membership_duration @@ -205,7 +203,7 @@ class AccountEndpoint(SeleneEndpoint): def _add_account(self, email_address, password): membership_type = self.request_data['support']['membership'] membership = None - if membership_type != NO_MEMBERSHIP: + if membership_type is not None: payment_token = self.request_data['support']['paymentToken'] email = self.request_data['login']['userEnteredEmail'] plan = self._get_plan(membership_type).stripe_plan