Add integration tests

This commit is contained in:
Roman Mogylatov 2021-02-23 18:03:09 -05:00
parent 5121b5c070
commit 3c3c6def6d
6 changed files with 309 additions and 0 deletions

View File

@ -0,0 +1,49 @@
version: "1"
providers:
core:
provider: Container
providers:
config:
provider: Configuration
gateways:
provider: Container
providers:
database_client:
provider: Singleton
provides: sqlite3.connect
args:
- core.config.database.dsn
s3_client:
provider: Singleton
provides: boto3.client
kwargs:
service_name: s3
aws_access_key_id: core.config.aws.access_key_id
aws_secret_access_key: core.config.aws.secret_access_key
services:
provider: Container
providers:
user:
provider: Factory
provides: schemasample.services.UserService
kwargs:
db: gateways.database_client
auth:
provider: Factory
provides: schemasample.services.AuthService
kwargs:
db: gateways.database_client
token_ttl: core.config.auth.token_ttl.as_int()
photo:
provider: Factory
provides: schemasample.services.PhotoService
kwargs:
db: gateways.database_client
s3: gateways.s3_client

View File

@ -0,0 +1,39 @@
version: "1"
providers:
config:
provider: Configuration
database_client:
provider: Singleton
provides: sqlite3.connect
args:
- config.database.dsn
s3_client:
provider: Singleton
provides: boto3.client
kwargs:
service_name: s3
aws_access_key_id: config.aws.access_key_id
aws_secret_access_key: config.aws.secret_access_key
user_service:
provider: Factory
provides: schemasample.services.UserService
kwargs:
db: database_client
auth_service:
provider: Factory
provides: schemasample.services.AuthService
kwargs:
db: database_client
token_ttl: config.auth.token_ttl.as_int()
photo_service:
provider: Factory
provides: schemasample.services.PhotoService
kwargs:
db: database_client
s3: s3_client

View File

@ -0,0 +1,56 @@
"""Services module."""
import logging
import sqlite3
from typing import Dict
from mypy_boto3_s3 import S3Client
class BaseService:
def __init__(self) -> None:
self.logger = logging.getLogger(
f'{__name__}.{self.__class__.__name__}',
)
class UserService(BaseService):
def __init__(self, db: sqlite3.Connection) -> None:
self.db = db
super().__init__()
def get_user(self, email: str) -> Dict[str, str]:
self.logger.debug('User %s has been found in database', email)
return {'email': email, 'password_hash': '...'}
class AuthService(BaseService):
def __init__(self, db: sqlite3.Connection, token_ttl: int) -> None:
self.db = db
self.token_ttl = token_ttl
super().__init__()
def authenticate(self, user: Dict[str, str], password: str) -> None:
assert password is not None
self.logger.debug(
'User %s has been successfully authenticated',
user['email'],
)
class PhotoService(BaseService):
def __init__(self, db: sqlite3.Connection, s3: S3Client) -> None:
self.db = db
self.s3 = s3
super().__init__()
def upload_photo(self, user: Dict[str, str], photo_path: str) -> None:
self.logger.debug(
'Photo %s has been successfully uploaded by user %s',
photo_path,
user['email'],
)

View File

@ -0,0 +1 @@
"""Schema tests."""

View File

@ -0,0 +1,164 @@
import pathlib
import unittest
import sqlite3
import yaml
from dependency_injector import containers
# Runtime import
import os
_TOP_DIR = os.path.abspath(
os.path.sep.join((
os.path.dirname(__file__),
'../',
)),
)
_SAMPLES_DIR = os.path.abspath(
os.path.sep.join((
os.path.dirname(__file__),
'../samples/',
)),
)
import sys
sys.path.append(_SAMPLES_DIR)
from schemasample.services import UserService, AuthService, PhotoService
class TestSchemaSingleContainer(unittest.TestCase):
def test(self):
container = containers.DynamicContainer()
schema_path = pathlib.Path(__file__).parent.parent / 'samples' / 'schemasample' / 'container-single.yml'
# TODO: from_yaml_schema()
with open(schema_path) as file:
schema = yaml.load(file, yaml.Loader)
container.from_schema(schema)
container.config.from_dict({
'database': {
'dsn': ':memory:',
},
'aws': {
'access_key_id': 'KEY',
'secret_access_key': 'SECRET',
},
'auth': {
'token_ttl': 3600,
},
})
# User service
user_service1 = container.user_service()
user_service2 = container.user_service()
self.assertIsInstance(user_service1, UserService)
self.assertIsInstance(user_service2, UserService)
self.assertIsNot(user_service1, user_service2)
self.assertIsInstance(user_service1.db, sqlite3.Connection)
self.assertIsInstance(user_service2.db, sqlite3.Connection)
self.assertIs(user_service1.db, user_service2.db)
# Auth service
auth_service1 = container.auth_service()
auth_service2 = container.auth_service()
self.assertIsInstance(auth_service1, AuthService)
self.assertIsInstance(auth_service2, AuthService)
self.assertIsNot(auth_service1, auth_service2)
self.assertIsInstance(auth_service1.db, sqlite3.Connection)
self.assertIsInstance(auth_service2.db, sqlite3.Connection)
self.assertIs(auth_service1.db, auth_service2.db)
self.assertIs(auth_service1.db, container.database_client())
self.assertIs(auth_service2.db, container.database_client())
self.assertEqual(auth_service1.token_ttl, 3600)
self.assertEqual(auth_service2.token_ttl, 3600)
# Photo service
photo_service1 = container.photo_service()
photo_service2 = container.photo_service()
self.assertIsInstance(photo_service1, PhotoService)
self.assertIsInstance(photo_service2, PhotoService)
self.assertIsNot(photo_service1, photo_service2)
self.assertIsInstance(photo_service1.db, sqlite3.Connection)
self.assertIsInstance(photo_service2.db, sqlite3.Connection)
self.assertIs(photo_service1.db, photo_service2.db)
self.assertIs(photo_service1.db, container.database_client())
self.assertIs(photo_service2.db, container.database_client())
self.assertIs(photo_service1.s3, photo_service2.s3)
self.assertIs(photo_service1.s3, container.s3_client())
self.assertIs(photo_service2.s3, container.s3_client())
class TestSchemaMultipleContainers(unittest.TestCase):
def test(self):
container = containers.DynamicContainer()
schema_path = pathlib.Path(__file__).parent.parent / 'samples' / 'schemasample' / 'container-multiple.yml'
# TODO: from_yaml_schema()
with open(schema_path) as file:
schema = yaml.load(file, yaml.Loader)
container.from_schema(schema)
container.core.config.from_dict({
'database': {
'dsn': ':memory:',
},
'aws': {
'access_key_id': 'KEY',
'secret_access_key': 'SECRET',
},
'auth': {
'token_ttl': 3600,
},
})
# User service
user_service1 = container.services.user()
user_service2 = container.services.user()
self.assertIsInstance(user_service1, UserService)
self.assertIsInstance(user_service2, UserService)
self.assertIsNot(user_service1, user_service2)
self.assertIsInstance(user_service1.db, sqlite3.Connection)
self.assertIsInstance(user_service2.db, sqlite3.Connection)
self.assertIs(user_service1.db, user_service2.db)
# Auth service
auth_service1 = container.services.auth()
auth_service2 = container.services.auth()
self.assertIsInstance(auth_service1, AuthService)
self.assertIsInstance(auth_service2, AuthService)
self.assertIsNot(auth_service1, auth_service2)
self.assertIsInstance(auth_service1.db, sqlite3.Connection)
self.assertIsInstance(auth_service2.db, sqlite3.Connection)
self.assertIs(auth_service1.db, auth_service2.db)
self.assertIs(auth_service1.db, container.gateways.database_client())
self.assertIs(auth_service2.db, container.gateways.database_client())
self.assertEqual(auth_service1.token_ttl, 3600)
self.assertEqual(auth_service2.token_ttl, 3600)
# Photo service
photo_service1 = container.services.photo()
photo_service2 = container.services.photo()
self.assertIsInstance(photo_service1, PhotoService)
self.assertIsInstance(photo_service2, PhotoService)
self.assertIsNot(photo_service1, photo_service2)
self.assertIsInstance(photo_service1.db, sqlite3.Connection)
self.assertIsInstance(photo_service2.db, sqlite3.Connection)
self.assertIs(photo_service1.db, photo_service2.db)
self.assertIs(photo_service1.db, container.gateways.database_client())
self.assertIs(photo_service2.db, container.gateways.database_client())
self.assertIs(photo_service1.s3, photo_service2.s3)
self.assertIs(photo_service1.s3, container.gateways.s3_client())
self.assertIs(photo_service2.s3, container.gateways.s3_client())