refactored endpoints.api.subscribe to use abstracted data interface

This commit is contained in:
alecmerdler 2017-06-27 14:00:23 -07:00 committed by Alec Merdler
parent 0cbe3bdf73
commit 791bd5aefc
4 changed files with 99 additions and 11 deletions

View file

@ -1,32 +1,28 @@
""" Subscribe to plans. """ """ Subscribe to plans. """
import logging import logging
import stripe import stripe
import features
from app import billing from app import billing
from endpoints.api import request_error, log_action from endpoints.api import request_error, log_action
from endpoints.exception import NotFound
from data import model
from data.billing import PLANS from data.billing import PLANS
from endpoints.api.subscribe_models_pre_oci import data_model as model
import features from endpoints.exception import NotFound
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def check_repository_usage(user_or_org, plan_found): def check_repository_usage(user_or_org, plan_found):
private_repos = model.user.get_private_repo_count(user_or_org.username) private_repos = model.get_private_repo_count(user_or_org.username)
if plan_found is None: if plan_found is None:
repos_allowed = 0 repos_allowed = 0
else: else:
repos_allowed = plan_found['privateRepos'] repos_allowed = plan_found['privateRepos']
if private_repos > repos_allowed: if private_repos > repos_allowed:
model.notification.create_unique_notification('over_private_usage', user_or_org, model.create_unique_notification('over_private_usage', user_or_org.username, {'namespace': user_or_org.username})
{'namespace': user_or_org.username})
else: else:
model.notification.delete_notifications_by_kind(user_or_org, 'over_private_usage') model.delete_notifications_by_kind(user_or_org.username, 'over_private_usage')
def carderror_response(exc): def carderror_response(exc):
@ -70,7 +66,7 @@ def subscribe(user, plan, token, require_business_plan):
user.username) user.username)
raise request_error(message='No matching plan found') raise request_error(message='No matching plan found')
private_repos = model.user.get_private_repo_count(user.username) private_repos = model.get_private_repo_count(user.username)
# This is the default response # This is the default response
response_json = { response_json = {

View file

@ -0,0 +1,26 @@
from abc import ABCMeta, abstractmethod
from six import add_metaclass
@add_metaclass(ABCMeta)
class SubscribeInterface(object):
"""
Interface that represents all data store interactions required by the subscribe API endpoint.
"""
@abstractmethod
def get_private_repo_count(self, username):
"""
Returns the number of private repositories for a given username or namespace.
"""
@abstractmethod
def create_unique_notification(self, kind_name, target_username, metadata={}):
"""
Creates a notification using the given parameters.
"""
@abstractmethod
def delete_notifications_by_kind(self, target_username, kind_name):
"""
Remove notifications for a target based on given kind.
"""

View file

@ -0,0 +1,23 @@
from data.model.notification import create_unique_notification, delete_notifications_by_kind
from data.model.user import get_private_repo_count, get_user_or_org
from endpoints.api.subscribe_models_interface import SubscribeInterface
class PreOCIModel(SubscribeInterface):
"""
PreOCIModel implements the data model for build triggers using a database schema
before it was changed to support the OCI specification.
"""
def get_private_repo_count(self, username):
return get_private_repo_count(username)
def create_unique_notification(self, kind_name, target_username, metadata={}):
target = get_user_or_org(target_username)
create_unique_notification(kind_name, target, metadata)
def delete_notifications_by_kind(self, target_username, kind_name):
target = get_user_or_org(target_username)
delete_notifications_by_kind(target, kind_name)
data_model = PreOCIModel()

View file

@ -0,0 +1,43 @@
import pytest
from mock import patch
from endpoints.api.subscribe_models_pre_oci import data_model
@pytest.mark.parametrize('username,repo_count', [
('devtable', 3)
])
def test_get_private_repo_count(username, repo_count):
with patch('endpoints.api.subscribe_models_pre_oci.get_private_repo_count') as mock_get_private_reop_count:
mock_get_private_reop_count.return_value = repo_count
count = data_model.get_private_repo_count(username)
mock_get_private_reop_count.assert_called_once_with(username)
assert count == repo_count
@pytest.mark.parametrize('kind_name,target_username,metadata', [
('over_private_usage', 'devtable', {'namespace': 'devtable'})
])
def test_create_unique_notification(kind_name, target_username, metadata):
with patch('endpoints.api.subscribe_models_pre_oci.get_user_or_org') as mock_get_user_or_org:
mock_get_user_or_org.return_value = {'username': target_username}
with patch('endpoints.api.subscribe_models_pre_oci.create_unique_notification') as mock_create_unique_notification:
data_model.create_unique_notification(kind_name, target_username, metadata)
mock_get_user_or_org.assert_called_once_with(target_username)
mock_create_unique_notification.assert_called_once_with(kind_name, mock_get_user_or_org.return_value, metadata)
@pytest.mark.parametrize('target_username,kind_name', [
('devtable', 'over_private_usage')
])
def test_delete_notifications_by_kind(target_username, kind_name):
with patch('endpoints.api.subscribe_models_pre_oci.get_user_or_org') as mock_get_user_or_org:
mock_get_user_or_org.return_value = {'username': target_username}
with patch('endpoints.api.subscribe_models_pre_oci.delete_notifications_by_kind') as mock_delete_notifications_by_kind:
data_model.delete_notifications_by_kind(target_username, kind_name)
mock_get_user_or_org.assert_called_once_with(target_username)
mock_delete_notifications_by_kind.assert_called_once_with(mock_get_user_or_org.return_value, kind_name)