refactored endpoints.api.subscribe to use abstracted data interface
This commit is contained in:
parent
0cbe3bdf73
commit
791bd5aefc
4 changed files with 99 additions and 11 deletions
|
@ -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 = {
|
||||||
|
|
26
endpoints/api/subscribe_models_interface.py
Normal file
26
endpoints/api/subscribe_models_interface.py
Normal 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.
|
||||||
|
"""
|
23
endpoints/api/subscribe_models_pre_oci.py
Normal file
23
endpoints/api/subscribe_models_pre_oci.py
Normal 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()
|
43
endpoints/api/test/test_subscribe_models_pre_oci.py
Normal file
43
endpoints/api/test/test_subscribe_models_pre_oci.py
Normal 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)
|
||||||
|
|
Reference in a new issue