547 lines
21 KiB
Python
547 lines
21 KiB
Python
""" unit tests (mainly for code coverage)
|
|
"""
|
|
import StringIO
|
|
import os
|
|
import sys
|
|
|
|
import json
|
|
import pytest
|
|
from mock import call, patch, Mock
|
|
from requests import Response, exceptions
|
|
|
|
from hobo.agent.common.management.commands.hobo_deploy import (
|
|
replace_file, Command, CommandError)
|
|
from hobo.agent.hobo.management.commands.hobo_deploy import Command as HoboCommand
|
|
from hobo.environment.models import Variable, Combo, Hobo, Wcs
|
|
from hobo.multitenant.middleware import TenantNotFound
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_themes(settings, tmpdir):
|
|
THEMES="""
|
|
[
|
|
{
|
|
"id": "alfortville",
|
|
"label": "Alfortville",
|
|
"variables": {
|
|
"css_variant": "alfortville",
|
|
"no_extra_js": false,
|
|
"theme_color": "#804697"
|
|
},
|
|
"overlay": "foobar"
|
|
},
|
|
{
|
|
"id": "publik",
|
|
"label": "Publik",
|
|
"variables": {
|
|
"css_variant": "publik",
|
|
"no_extra_js": false,
|
|
"theme_color": "#E80E89"
|
|
}
|
|
}
|
|
]
|
|
"""
|
|
base_dir = str(tmpdir.mkdir('themes'))
|
|
settings.THEMES_DIRECTORY = base_dir
|
|
|
|
themes_dir = os.path.join(base_dir, 'publik-base')
|
|
os.mkdir(themes_dir)
|
|
with open(os.path.join(themes_dir, 'themes.json'), 'w') as handler:
|
|
handler.write(THEMES)
|
|
|
|
# populate 'foobar' overlay
|
|
themes_dir = os.path.join(base_dir, 'foobar')
|
|
os.mkdir(themes_dir)
|
|
for part in ('static', 'templates'):
|
|
os.mkdir(os.path.join(themes_dir, part))
|
|
|
|
|
|
def test_replace_file(tmpdir):
|
|
path = str(tmpdir) + '/my_file.txt'
|
|
|
|
content = 'content of my new file'
|
|
replace_file(path, content)
|
|
with open(path, 'r') as handler:
|
|
assert handler.read() == content
|
|
|
|
content = 'new content for my file'
|
|
replace_file(path, content)
|
|
with open(path, 'r') as handler:
|
|
assert handler.read() == content
|
|
|
|
|
|
def test_handle_from_scratch():
|
|
"""API using JSON from file or from stdin"""
|
|
command = Command()
|
|
CONTENT = """
|
|
{
|
|
"services": [{
|
|
"service-id": "combo"
|
|
}]
|
|
}
|
|
"""
|
|
command.deploy = Mock()
|
|
EXPECTED = [call('https://combo.dev.publik.love/',
|
|
{'services': [{'service-id': 'combo'}]}, None)]
|
|
|
|
# handle from file
|
|
command.deploy.reset_mock()
|
|
with patch('hobo.agent.common.management.commands.hobo_deploy.open') as mocked_open:
|
|
mocked_open.side_effect = [StringIO.StringIO(CONTENT)]
|
|
command.handle('https://combo.dev.publik.love/', 'envbof.json')
|
|
assert command.deploy.mock_calls == EXPECTED
|
|
|
|
# handle using a pipe
|
|
command.deploy.reset_mock()
|
|
backup = sys.stdin
|
|
sys.stdin = StringIO.StringIO(CONTENT)
|
|
command.handle('https://combo.dev.publik.love/', '-')
|
|
sys.stdin = backup
|
|
assert command.deploy.mock_calls == EXPECTED
|
|
|
|
# JSON having syntax error
|
|
command.deploy.reset_mock()
|
|
with patch('hobo.agent.common.management.commands.hobo_deploy.open') as mocked_open:
|
|
mocked_open.side_effect = [StringIO.StringIO('malformated JSON')]
|
|
with pytest.raises(ValueError, match='No JSON object could be decoded'):
|
|
command.handle('https://combo.dev.publik.love/', 'env.json')
|
|
assert command.deploy.mock_calls == []
|
|
|
|
# missing args
|
|
with pytest.raises(CommandError, match='missing args'):
|
|
command.handle('https://combo.dev.publik.love/')
|
|
with pytest.raises(CommandError, match='missing args'):
|
|
command.handle(json_filename='env.json')
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.TenantMiddleware.get_tenants')
|
|
def test_handle_redeploy_case(mocked_get_tenants):
|
|
"""API using JSON from previous one we put on tenant"""
|
|
command = Command()
|
|
command.deploy = Mock()
|
|
tenant = Mock()
|
|
|
|
# redeploy
|
|
command.deploy.reset_mock()
|
|
ENVIRONMENT = {'services': [{'this': True,
|
|
'base_url': 'https://combo.dev.publik.love/',
|
|
'service-id': 'combo'}]}
|
|
tenant.get_hobo_json = Mock(return_value=ENVIRONMENT)
|
|
mocked_get_tenants.return_value = [tenant]
|
|
command.handle(redeploy=True)
|
|
assert command.deploy.mock_calls == [ # ignore_timestamp is set to True
|
|
call('https://combo.dev.publik.love/', ENVIRONMENT, True)]
|
|
|
|
# redeploy having wrong JSON content: no 'base_url' entry
|
|
command.deploy.reset_mock()
|
|
tenant.get_hobo_json = Mock(return_value=
|
|
{'services': [{'service-id': 'combo', 'this': True}]})
|
|
mocked_get_tenants.return_value = [tenant]
|
|
with pytest.raises(KeyError, match='base_url'):
|
|
command.handle(redeploy=True)
|
|
assert command.deploy.mock_calls == []
|
|
|
|
# redeploy having wrong JSON content: 'this' entry not found
|
|
command.deploy.reset_mock()
|
|
tenant.get_hobo_json = Mock(return_value={'services': [{'service-id': 'combo'}]})
|
|
mocked_get_tenants.return_value = [tenant]
|
|
command.handle(redeploy=True)
|
|
assert command.deploy.mock_calls == []
|
|
|
|
# IOError
|
|
command.deploy.reset_mock()
|
|
tenant.get_hobo_json = Mock(side_effect=IOError)
|
|
mocked_get_tenants.return_value = [tenant]
|
|
command.handle(redeploy=True)
|
|
assert command.deploy.mock_calls == []
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.TenantMiddleware.get_tenant_by_hostname')
|
|
def test_deploy(mocked_get_tenant_by_hostname, tmpdir):
|
|
command = Command()
|
|
command.deploy_specifics = Mock()
|
|
tenant = Mock()
|
|
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
base_url = 'https://combo.dev.publik.love/'
|
|
tenant_hobo_json = os.path.join(str(tmpdir), 'hobo.json')
|
|
ENVIRONMENT = {'services': [{'service-id': 'combo', 'base_url': base_url}],
|
|
'timestamp': '001'}
|
|
|
|
def assert_deployed():
|
|
assert mocked_get_tenant_by_hostname.mock_calls[0] == call('combo.dev.publik.love')
|
|
assert command.deploy_specifics.mock_calls == [
|
|
call({'services': [{'base_url': 'https://combo.dev.publik.love/',
|
|
'service-id': 'combo',
|
|
'this': True,}],
|
|
'timestamp': '001'},
|
|
tenant)]
|
|
with open(tenant_hobo_json, 'r') as handler: # hobo.json file
|
|
content = json.load(handler)
|
|
assert ENVIRONMENT['services'][0]['this'] is True # new entry added
|
|
assert json.dumps(content, sort_keys=True), json.dumps(ENVIRONMENT, sort_keys=True)
|
|
|
|
# create tenant first
|
|
command.deploy_specifics.reset_mock()
|
|
mocked_get_tenant_by_hostname.reset_mock()
|
|
mocked_get_tenant_by_hostname.side_effect = [TenantNotFound, tenant]
|
|
with patch('hobo.agent.common.management.commands.hobo_deploy.call_command'
|
|
) as mocked_call_command:
|
|
command.deploy(base_url, ENVIRONMENT, None)
|
|
assert mocked_call_command.mock_calls == [
|
|
call('create_tenant', 'combo.dev.publik.love')]
|
|
assert_deployed()
|
|
|
|
# already there (timestamp do not change)
|
|
command.deploy_specifics.reset_mock()
|
|
mocked_get_tenant_by_hostname.side_effect = [tenant]
|
|
command.deploy(base_url, ENVIRONMENT, None)
|
|
assert command.deploy_specifics.mock_calls == []
|
|
|
|
# force re-deploy
|
|
command.deploy_specifics.reset_mock()
|
|
mocked_get_tenant_by_hostname.reset_mock()
|
|
mocked_get_tenant_by_hostname.side_effect = [tenant]
|
|
command.deploy(base_url, ENVIRONMENT, True)
|
|
assert_deployed()
|
|
|
|
# early exit, we don't redeploy secondary services
|
|
command.deploy_specifics.reset_mock()
|
|
env = dict(ENVIRONMENT)
|
|
env['services'][0]['secondary'] = True
|
|
command.deploy(base_url, env, None)
|
|
assert command.deploy_specifics.mock_calls == []
|
|
|
|
|
|
def test_deploy_specific():
|
|
"""stupid test"""
|
|
command = Command()
|
|
command.generate_saml_keys = Mock()
|
|
command.configure_service_provider = Mock()
|
|
command.configure_theme = Mock()
|
|
command.configure_template = Mock()
|
|
|
|
command.deploy_specifics('my_hobo_env', 'my_tenant')
|
|
assert command.generate_saml_keys.mock_calls == [call('my_tenant', prefix='sp-')]
|
|
assert command.configure_service_provider.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
assert command.configure_theme.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
assert command.configure_template.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
|
|
|
|
def test_generate_saml_keys(tmpdir):
|
|
"""create an RSA key and its x509 certificate"""
|
|
command = Command()
|
|
tenant = Mock()
|
|
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
tenant.domain_url = 'combo.dev.publik.love'
|
|
|
|
command.generate_saml_keys(tenant)
|
|
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
key = handler.read()
|
|
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
crt = handler.read()
|
|
|
|
# if files exist don't regenerate them
|
|
command.generate_saml_keys(tenant)
|
|
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
assert key == handler.read()
|
|
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
assert crt == handler.read()
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.requests.get')
|
|
def test_configure_service_provider(mocked_get, tmpdir):
|
|
"""create TENANT/idp-metadata-ID.xml file"""
|
|
command = Command()
|
|
tenant = Mock()
|
|
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
response1 = Response()
|
|
response1._content = 'my saml idp metadata (1)'
|
|
response1.status_code = 200
|
|
response2 = Response()
|
|
response2._content = 'my saml idp metadata (2)'
|
|
response2.status_code = 200
|
|
tenant_idp_metadata = '%s/idp-metadata-%s.xml' % (str(tmpdir), '1')
|
|
|
|
ENVIRONMENT = {'services': [
|
|
{'service-id': 'combo',
|
|
'saml-idp-metadata-url': 'https://combo.dev.publik.love/accounts/mellon/metadata/',
|
|
'id': 1},
|
|
{'service-id': 'wcs',
|
|
'saml-idp-metadata-url': 'https://wcs.dev.publik.love/saml/metadata',
|
|
'id': 1},
|
|
]}
|
|
|
|
# normal case (stop when configuration on a service success for this tenant)
|
|
mocked_get.side_effect = [response1]
|
|
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
with open(tenant_idp_metadata, 'r') as handler:
|
|
assert handler.read() == 'my saml idp metadata (1)'
|
|
|
|
# no 'idp_url' JSON entry
|
|
env = {'services': [{'service-id': 'combo', 'id': 1}]}
|
|
os.remove(tenant_idp_metadata)
|
|
command.configure_service_provider(env, tenant)
|
|
with pytest.raises(IOError, match='No such file or directory'):
|
|
open(tenant_idp_metadata, 'r')
|
|
|
|
# idp not available
|
|
response1.status_code = 500
|
|
mocked_get.side_effect = [exceptions.RequestException, response1]
|
|
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
with pytest.raises(IOError, match='No such file or directory'):
|
|
open(tenant_idp_metadata, 'r')
|
|
|
|
# case when idp is becoming available
|
|
mocked_get.side_effect = [response1, response2]
|
|
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
with open(tenant_idp_metadata, 'r') as handler:
|
|
assert handler.read() == 'my saml idp metadata (2)'
|
|
|
|
|
|
def test_get_theme(fake_themes):
|
|
"""return the service's theme"""
|
|
COMBO = {'service-id': 'combo'}
|
|
WCS = {'service-id': 'hobo', 'variables': {'theme': 'alfortville'}}
|
|
HOBO = {'service-id': 'hobo', 'variables': {'theme': 'unknown_theme'}}
|
|
ENVIRONMENT = {'services': [COMBO, WCS, HOBO], 'variables': {'theme': 'publik'}}
|
|
command = Command()
|
|
|
|
# main case
|
|
command.me = COMBO
|
|
assert command.get_theme(ENVIRONMENT)['id'] == 'publik'
|
|
|
|
# service having theme overloaded
|
|
command.me = WCS
|
|
assert command.get_theme(ENVIRONMENT)['id'] == 'alfortville'
|
|
|
|
# theme not specified
|
|
command.me = COMBO
|
|
assert command.get_theme({'services': [COMBO, WCS, HOBO]}) is None
|
|
|
|
# unknown theme
|
|
command.me = HOBO
|
|
assert command.get_theme(ENVIRONMENT) is None
|
|
|
|
|
|
def test_configure_theme(fake_themes, tmpdir):
|
|
"""make symlink for TENANT/theme
|
|
and TENANT/static, TENANT/templates on overlay
|
|
"""
|
|
COMBO = {'service-id': 'combo'}
|
|
WCS = {'service-id': 'hobo', 'variables': {'theme': 'alfortville'}} # overlay on fixture
|
|
HOBO = {'service-id': 'hobo', 'variables': {'theme': 'unknown_theme'}}
|
|
ENVIRONMENT = {'services': [COMBO, WCS, HOBO], 'variables': {'theme': 'publik'}}
|
|
command = Command()
|
|
command.me = COMBO
|
|
|
|
tenant = Mock()
|
|
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
theme_path = '%s/theme' % str(tmpdir)
|
|
static_path = '%s/static' % str(tmpdir)
|
|
templates_path = '%s/templates' % str(tmpdir)
|
|
|
|
# main case: (remove 'static' and/or 'templates' links and empty directories too)
|
|
os.mkdir(static_path)
|
|
os.symlink(str(tmpdir), templates_path)
|
|
command.configure_theme(ENVIRONMENT, tenant)
|
|
assert os.path.islink(theme_path)
|
|
assert os.path.exists(static_path) is False
|
|
assert os.path.exists(templates_path) is False
|
|
|
|
# overlay provided: build links to the 'overlay' directory
|
|
os.symlink(str(tmpdir), static_path)
|
|
os.mkdir(templates_path)
|
|
command.me = WCS
|
|
command.configure_theme(ENVIRONMENT, tenant)
|
|
assert os.readlink(static_path) == '%s/themes/foobar/static' % str(tmpdir)
|
|
assert os.readlink(templates_path) == '%s/themes/foobar/templates' % str(tmpdir)
|
|
|
|
# retrieve on error (if server hangs during 'atomic_symlink')
|
|
os.unlink(theme_path)
|
|
os.symlink(str(tmpdir), theme_path + '.tmp')
|
|
command.configure_theme(ENVIRONMENT, tenant)
|
|
assert os.path.islink(theme_path)
|
|
assert os.path.islink(static_path) # to compare with result we get bellow
|
|
|
|
# do not 'overlay' non-empty 'static' and/or 'templates' true directories
|
|
os.unlink(static_path)
|
|
os.mkdir(static_path)
|
|
os.mkdir(os.path.join(static_path, 'some_dir'))
|
|
command.configure_theme(ENVIRONMENT, tenant)
|
|
assert os.path.isdir(static_path)
|
|
|
|
# no theme provided
|
|
os.unlink(theme_path)
|
|
command.me = HOBO
|
|
command.configure_theme(ENVIRONMENT, tenant)
|
|
assert os.path.exists(theme_path) is False
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.get_commands')
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.tenant_context')
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.call_command')
|
|
def test_configure_template(mocked_call_command, mocked_tenant_context,
|
|
mocked_get_commands):
|
|
command = Command()
|
|
tenant = Mock()
|
|
ENVIRONMENT = {'services': [{'service-id': 'combo',
|
|
'template_name': 'my_template',
|
|
'this': True}]}
|
|
|
|
# import_template.py located into hobo/agent/common: always belongs to command object
|
|
# TODO: dead condition
|
|
mocked_get_commands.return_value = ['import_template', '...']
|
|
|
|
# main case
|
|
command.configure_template(ENVIRONMENT, tenant)
|
|
assert mocked_call_command.mock_calls == [call('import_template', 'my_template')]
|
|
|
|
# no template_name entry provided
|
|
mocked_call_command.reset_mock()
|
|
del ENVIRONMENT['services'][0]['template_name']
|
|
command.configure_template(ENVIRONMENT, tenant)
|
|
assert mocked_call_command.mock_calls == []
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
def test_hobo_deploy_specifics_alone(mocked_tenant_context, mocked_super, db):
|
|
"""build database content used later to generate hobo.json.
|
|
tests using tenants are located into tests_multipublik/test_multipublik.py
|
|
"""
|
|
command = HoboCommand()
|
|
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
'slug': 'hobo',
|
|
'title': 'Hobo',
|
|
'base_url': 'https://hobo.dev.publik.love/',
|
|
'this': True},
|
|
{'service-id': 'combo',
|
|
'slug': 'portal',
|
|
'title': 'Compte citoyen',
|
|
'base_url': 'https://combo.dev.publik.love/'},
|
|
{'service-id': 'wcs',
|
|
'slug': 'eservices',
|
|
'title': 'D\u00e9marches',
|
|
'base_url': 'wcs.dev.publik.love'},
|
|
{'service-id': 'wrong id',
|
|
'base_url': 'https://wrong.dev.publik.love/'}]}
|
|
|
|
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
|
|
assert mocked_super.mock_calls == [call(ENVIRONMENT, 'tenant')]
|
|
assert len(Hobo.objects.all()) == 0
|
|
assert len(Combo.objects.all()) == 1
|
|
assert len(Wcs.objects.all()) == 1
|
|
combo = Combo.objects.all()[0]
|
|
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
assert combo.slug == '_interco_portal'
|
|
|
|
# define global variables (twice)
|
|
ou_label = Variable.objects.get(name='ou-label')
|
|
ou_slug = Variable.objects.get(name='ou-slug')
|
|
assert ou_label.value == 'Hobo'
|
|
assert ou_slug.value == 'hobo'
|
|
assert ou_label.service_pk is None
|
|
assert ou_slug.service_pk is None
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
def test_hobo_deploy_specifics_primary(mocked_tenant_context, mocked_super, db):
|
|
"""first deployement: do nothing for secondary hobo-services
|
|
same behaviour as previous 'alone' test
|
|
"""
|
|
command = HoboCommand()
|
|
wcs_url = 'https://wcs.dev.publik.love/'
|
|
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
'slug': 'hobo',
|
|
'title': 'Hobo primary',
|
|
'base_url': 'https://hobo1.dev.publik.love/',
|
|
'this': True},
|
|
{'service-id': 'combo',
|
|
'slug': 'portal',
|
|
'title': 'Compte citoyen',
|
|
'base_url': 'https://combo.dev.publik.love/'},
|
|
{'service-id': 'wcs',
|
|
'slug': 'eservices',
|
|
'title': 'skipped as url already in use',
|
|
'base_url': wcs_url},
|
|
{'service-id': 'hobo',
|
|
'slug': 'hobo',
|
|
'title': 'Hobo secondary',
|
|
'base_url': 'https://hobo2.dev.publik.love/',
|
|
'secondary': True}]}
|
|
|
|
# make the wcs service already deployed
|
|
Wcs.objects.get_or_create(base_url=wcs_url, secondary=False)
|
|
|
|
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
|
|
assert mocked_super.mock_calls == [call(ENVIRONMENT, 'tenant')]
|
|
assert len(Hobo.objects.all()) == 0
|
|
assert len(Combo.objects.all()) == 1
|
|
assert len(Wcs.objects.all()) == 1 # the wcs service already set upper
|
|
combo = Combo.objects.all()[0]
|
|
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
assert combo.slug == '_interco_portal'
|
|
|
|
# define global variables
|
|
ou_label = Variable.objects.get(name='ou-label')
|
|
ou_slug = Variable.objects.get(name='ou-slug')
|
|
assert ou_label.value == 'Hobo primary'
|
|
assert ou_slug.value == 'hobo'
|
|
assert ou_label.service_pk is None
|
|
assert ou_slug.service_pk is None
|
|
|
|
|
|
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
def test_hobo_deploy_specifics_secondary(mocked_tenant_context, mocked_super, db):
|
|
"""next deployements: skip generic tasks and add 'ou' variables
|
|
"""
|
|
command = HoboCommand()
|
|
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
'slug': 'hobo',
|
|
'title': 'Hobo primary',
|
|
'base_url': 'https://hobo1.dev.publik.love/'},
|
|
{'service-id': 'combo',
|
|
'slug': 'portal',
|
|
'title': 'Compte citoyen',
|
|
'base_url': 'https://combo.dev.publik.love/'},
|
|
{'service-id': 'hobo',
|
|
'slug': 'hobo',
|
|
'title': 'Hobo secondary',
|
|
'base_url': 'https://hobo2.dev.publik.love/',
|
|
'secondary': True,
|
|
'this': True}],
|
|
'variables': {'ou-label': 'my ou-label',
|
|
'ou-slug': 'my ou-slug'}}
|
|
|
|
# assert primary hobo is wanted
|
|
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
assert len(Combo.objects.all()) == 0
|
|
|
|
# make primary hobo already deployed
|
|
Hobo.objects.get_or_create(base_url='hobo1.dev.publik.love', secondary=False)
|
|
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
|
|
assert mocked_super.mock_calls == []
|
|
assert len(Hobo.objects.all()) == 1 # primary hobo set upper
|
|
assert len(Combo.objects.all()) == 1
|
|
combo = Combo.objects.all()[0]
|
|
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
assert combo.slug == '_my ou-slug_portal'
|
|
|
|
# variables are added to the services
|
|
ou_label = Variable.objects.get(name='ou-label')
|
|
ou_slug = Variable.objects.get(name='ou-slug')
|
|
assert ou_label.value == 'my ou-label'
|
|
assert ou_slug.value == 'my ou-slug'
|
|
assert ou_label.service_pk == combo.id
|
|
assert ou_slug.service_pk == combo.id
|
|
|
|
|
|
# Can't write test_authentic2_deploy_specifics as cannot import A2Command here:
|
|
#from hobo.agent.authentic2.management.commands.hobo_deploy import Command as A2Command
|
|
# -> tests_authentic/test_hobo_deploy.py
|