Merge pull request #740 from nofusscomputing/feature-next-release
This commit is contained in:
35
.github/ISSUE_TEMPLATE/new_model.md
vendored
35
.github/ISSUE_TEMPLATE/new_model.md
vendored
@ -33,6 +33,8 @@ Describe in detail the following:
|
||||
|
||||
- [ ] 🛠️ Migrations added
|
||||
|
||||
- [ ] ♻️ Serializer Created
|
||||
|
||||
- [ ] 🔄 [ViewSet Created](https://nofusscomputing.com/projects/centurion_erp/development/views/)
|
||||
|
||||
- [ ] 🔗 URL Route Added
|
||||
@ -52,9 +54,9 @@ Describe in detail the following:
|
||||
|
||||
- Sub-Models **_ONLY_**
|
||||
|
||||
- [ ] Model class variable `history_app_label` set to correct application label
|
||||
- [ ] Model class variable [`history_app_label`](https://nofusscomputing.com/projects/centurion_erp/development/models/#history) set to correct application label
|
||||
|
||||
- [ ] Model class variable `history_model_name` set to correct model label
|
||||
- [ ] Model class variable [`history_model_name`](https://nofusscomputing.com/projects/centurion_erp/development/models/#history) set to correct model label
|
||||
|
||||
- [ ] 📓 New [Notes model](https://nofusscomputing.com/projects/centurion_erp/development/core/model_notes/) created
|
||||
- [ ] 🆕 Model Created
|
||||
@ -77,16 +79,17 @@ Describe in detail the following:
|
||||
### 🧪 Tests
|
||||
|
||||
- Unit Tests
|
||||
- [ ] API Render (fields)
|
||||
- [ ] [Model](https://nofusscomputing.com/projects/centurion_erp/development/models/#tests)
|
||||
- [ ] Serializer
|
||||
- [ ] ViewSet
|
||||
- Function Test
|
||||
- [ ] ViewSet
|
||||
- [ ] History API Render (fields)
|
||||
- [ ] History Entries
|
||||
- [ ] API Metadata
|
||||
- [ ] API Permissions
|
||||
- [ ] API Render (fields)
|
||||
- [ ] History Entries
|
||||
- [ ] History API Render (fields)
|
||||
- [ ] Model
|
||||
- [ ] Serializer
|
||||
- [ ] ViewSet
|
||||
|
||||
|
||||
## ✅ Requirements
|
||||
@ -95,6 +98,24 @@ A Requirement is a must have. In addition will also be tested.
|
||||
|
||||
- [ ] Must have a [model_tag](https://nofusscomputing.com/projects/centurion_erp/user/core/markdown/#model-reference)
|
||||
|
||||
<!--
|
||||
|
||||
When detailing requirements the following must be taken into account:
|
||||
|
||||
- what the user should be able to do
|
||||
|
||||
- what the user should not be able to do
|
||||
|
||||
- what should occur when a user performs an action
|
||||
|
||||
-->
|
||||
|
||||
- Functional Requirements
|
||||
|
||||
|
||||
- Non-Functional Requirements
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- Add additional requirement here and as a check box list -->
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,9 +1,10 @@
|
||||
venv/**
|
||||
*/static/**
|
||||
__pycache__
|
||||
**.sqlite3
|
||||
**.sqlite*
|
||||
**.sqlite
|
||||
**.coverage
|
||||
.coverage*
|
||||
artifacts/
|
||||
**.tmp.*
|
||||
volumes/
|
||||
@ -19,3 +20,4 @@ package.json
|
||||
feature_flags.json
|
||||
coverage_*.json
|
||||
*-coverage.xml
|
||||
log/
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -23,4 +23,5 @@
|
||||
"yellow": 60,
|
||||
"green": 90
|
||||
},
|
||||
"telemetry.feedback.enabled": false,
|
||||
}
|
@ -1,3 +1,26 @@
|
||||
## Version 1.17.0
|
||||
|
||||
- Added setting for log files.
|
||||
|
||||
Enables user to specify a default path for centurion's logging. Add the following to your settings file `/etc/itsm/settings.py`
|
||||
|
||||
``` py
|
||||
LOG_FILES = {
|
||||
"centurion": "/var/log/centurion.log", # Normal Centurion Operations
|
||||
"weblog": "/var/log/weblog.log", # All web requests made to Centurion
|
||||
"rest_api": "/var/log/rest_api.log", # Rest API
|
||||
"catch_all":"/var/log/catch-all.log" # A catch all log. Note: does not log anything that has already been logged.
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
With this new setting, the previous setting `LOGGING` will no longer function.
|
||||
|
||||
- Renamed `Organization` model to `Tenant` so as to reflect what is actually is.
|
||||
|
||||
- `robots.txt` file now being served from the API container at path `/robots.txt` with `User-agent: *` and `Disallow: /`
|
||||
|
||||
|
||||
## Version 1.16.0
|
||||
|
||||
- Employees model added behind feature flag `2025-00002` and will remain behind this flag until production ready.
|
||||
|
@ -1,12 +1,15 @@
|
||||
import django
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
admin.site.unregister(Group)
|
||||
|
||||
class TeamInline(admin.TabularInline):
|
||||
|
@ -3,7 +3,7 @@ from django.db.models import Q
|
||||
|
||||
from app import settings
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
|
||||
from core.forms.common import CommonModelForm
|
||||
|
||||
|
@ -9,6 +9,7 @@ def permission_queryset():
|
||||
|
||||
apps = [
|
||||
'access',
|
||||
'accounting',
|
||||
'assistance',
|
||||
'config_management',
|
||||
'core',
|
||||
@ -36,14 +37,17 @@ def permission_queryset():
|
||||
'add_history',
|
||||
'add_organization',
|
||||
'add_taskresult',
|
||||
'add_ticketcommentaction',
|
||||
'change_checkin',
|
||||
'change_history',
|
||||
'change_organization',
|
||||
'change_taskresult',
|
||||
'change_ticketcommentaction',
|
||||
'delete_checkin',
|
||||
'delete_history',
|
||||
'delete_organization',
|
||||
'delete_taskresult',
|
||||
'delete_ticketcommentaction',
|
||||
'view_checkin',
|
||||
'view_history',
|
||||
]
|
||||
|
@ -1,18 +1,22 @@
|
||||
import django
|
||||
|
||||
from django.contrib.auth.middleware import (
|
||||
AuthenticationMiddleware,
|
||||
SimpleLazyObject,
|
||||
partial,
|
||||
)
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib.auth.models import Group
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
|
||||
from settings.models.app_settings import AppSettings
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
class RequestTenancy(MiddlewareMixin):
|
||||
"""Access Middleware
|
||||
|
25
app/access/migrations/0007_rename_organization_tenant.py
Normal file
25
app/access/migrations/0007_rename_organization_tenant.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.1.9 on 2025-05-14 11:06
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('access', '0005_entity_person_entityhistory_entitynotes_role_and_more'),
|
||||
('assistance', '0005_knowledgebasecategoryhistory_knowledgebasehistory'),
|
||||
('config_management', '0007_configgroupshistory_configgrouphostshistory_and_more'),
|
||||
('core', '0022_ticketcommentbase_ticketbase_ticketcommentsolution_and_more'),
|
||||
('devops', '0011_alter_gitgroup_unique_together_and_more'),
|
||||
('itam', '0010_alter_software_organization'),
|
||||
('itim', '0009_slmticket_requestticket'),
|
||||
('project_management', '0005_projecthistory_projectmilestonehistory_and_more'),
|
||||
('settings', '0011_appsettingshistory_externallinkhistory'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name = 'Organization',
|
||||
new_name = 'Tenant'
|
||||
),
|
||||
]
|
@ -0,0 +1,47 @@
|
||||
# Generated by Django 5.1.9 on 2025-05-14 13:48
|
||||
|
||||
import access.models.team
|
||||
import access.models.tenancy
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('access', '0007_rename_organization_tenant'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='tenant',
|
||||
options={'ordering': ['name'], 'verbose_name': 'Tenant', 'verbose_name_plural': 'Tenants'},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='entity',
|
||||
name='organization',
|
||||
field=models.ForeignKey(help_text='Tenancy this belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='+', to='access.tenant', validators=[access.models.tenancy.TenancyObject.validatate_organization_exists], verbose_name='Tenant'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='role',
|
||||
name='organization',
|
||||
field=models.ForeignKey(help_text='Tenancy this belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='+', to='access.tenant', validators=[access.models.tenancy.TenancyObject.validatate_organization_exists], verbose_name='Tenant'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='team',
|
||||
name='organization',
|
||||
field=models.ForeignKey(help_text='Tenant this belongs to', on_delete=django.db.models.deletion.CASCADE, to='access.tenant', validators=[access.models.team.Team.validatate_organization_exists], verbose_name='Tenant'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tenant',
|
||||
name='manager',
|
||||
field=models.ForeignKey(help_text='Manager for this Tenancy', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Manager'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tenant',
|
||||
name='name',
|
||||
field=models.CharField(help_text='Name of this Tenancy', max_length=50, unique=True, verbose_name='Name'),
|
||||
),
|
||||
]
|
@ -0,0 +1,135 @@
|
||||
|
||||
from django.contrib.auth.models import ContentType, Permission
|
||||
from django.db import migrations
|
||||
|
||||
from access.models.team import Team
|
||||
|
||||
ContentType.DoesNotExist
|
||||
|
||||
def add_tenancy_permissions(apps, schema_editor):
|
||||
|
||||
print('')
|
||||
print(f"Begin permission migration for rename of Organization to Tenant.")
|
||||
|
||||
try:
|
||||
|
||||
add_permission = Permission.objects.get(
|
||||
codename = 'add_tenant',
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = 'access',
|
||||
model = 'tenant',
|
||||
)
|
||||
)
|
||||
|
||||
change_permission = Permission.objects.get(
|
||||
codename = 'change_tenant',
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = 'access',
|
||||
model = 'tenant',
|
||||
)
|
||||
)
|
||||
|
||||
delete_permission = Permission.objects.get(
|
||||
codename = 'delete_tenant',
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = 'access',
|
||||
model = 'tenant',
|
||||
)
|
||||
)
|
||||
|
||||
view_permission = Permission.objects.get(
|
||||
codename = 'view_tenant',
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = 'access',
|
||||
model = 'tenant',
|
||||
)
|
||||
)
|
||||
|
||||
print(f' Searching for Teams.')
|
||||
|
||||
teams = Team.objects.select_related('group_ptr__permissions')
|
||||
|
||||
print(f'Found {str(len(teams))} Teams.')
|
||||
|
||||
for team in teams:
|
||||
|
||||
print(f' Processing Team {str(team.team_name)}.')
|
||||
|
||||
permissions = team.group_ptr.permissions.all()
|
||||
|
||||
print(f' Searching for Organization Permissions.')
|
||||
print(f' Found {str(len(permissions))} Permissions.')
|
||||
|
||||
for permission in permissions:
|
||||
|
||||
if '_organization' not in permission.codename:
|
||||
|
||||
continue
|
||||
|
||||
action = str(permission.codename).split('_')[0]
|
||||
|
||||
print(f' Found Organization Permission {str(action)}')
|
||||
|
||||
if action == 'add':
|
||||
|
||||
team.group_ptr.permissions.add( add_permission )
|
||||
|
||||
print(f' Add Tenant Permission {str(action)}')
|
||||
|
||||
team.group_ptr.permissions.remove( permission )
|
||||
|
||||
print(f' Remove Organization Permission {str(action)}')
|
||||
|
||||
elif action == 'change':
|
||||
|
||||
team.group_ptr.permissions.add( change_permission )
|
||||
|
||||
print(f' Add Tenant Permission {str(action)}')
|
||||
|
||||
team.group_ptr.permissions.remove( permission )
|
||||
|
||||
print(f' Remove Organization Permission {str(action)}')
|
||||
|
||||
elif action == 'delete':
|
||||
|
||||
team.group_ptr.permissions.add( delete_permission )
|
||||
|
||||
print(f' Add Tenant Permission {str(action)}')
|
||||
|
||||
team.group_ptr.permissions.remove( permission )
|
||||
|
||||
print(f' Remove Organization Permission {str(action)}')
|
||||
|
||||
elif action == 'view':
|
||||
|
||||
team.group_ptr.permissions.add( view_permission )
|
||||
|
||||
print(f' Add Tenant Permission {str(action)}')
|
||||
|
||||
team.group_ptr.permissions.remove( permission )
|
||||
|
||||
print(f' Remove Organization Permission {str(action)}')
|
||||
|
||||
|
||||
print(f' Completed Team {str(team.team_name)}.')
|
||||
|
||||
except ContentType.DoesNotExist:
|
||||
# DB is new so no content types. no migration to be done.
|
||||
pass
|
||||
|
||||
print(' Permission Migration Actions Complete.')
|
||||
|
||||
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('access', '0008_alter_tenant_options_alter_entity_organization_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(add_tenancy_permissions),
|
||||
]
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
# Generated by Django 5.1.9 on 2025-05-16 09:58
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('access', '0009_migrate_organization_permission_tenant'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Company',
|
||||
fields=[
|
||||
('entity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='access.entity')),
|
||||
('name', models.CharField(help_text='The name of this entity', max_length=80, verbose_name='Name')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Company',
|
||||
'verbose_name_plural': 'Companies',
|
||||
'ordering': ['name'],
|
||||
'sub_model_type': 'company',
|
||||
},
|
||||
bases=('access.entity',),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='entity',
|
||||
name='entity_type',
|
||||
field=models.CharField(help_text='Type this entity is', max_length=30, verbose_name='Entity Type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='person',
|
||||
name='dob',
|
||||
field=models.DateField(blank=True, help_text='The Persons Date of Birth (DOB)', null=True, verbose_name='DOB'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='person',
|
||||
name='m_name',
|
||||
field=models.CharField(blank=True, help_text='The persons middle name(s)', max_length=100, null=True, verbose_name='Middle Name(s)'),
|
||||
),
|
||||
]
|
@ -4,7 +4,7 @@ from django.contrib.auth.models import Group
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
|
||||
@ -260,7 +260,7 @@ class OrganizationMixin():
|
||||
self.permission_required = permissions_required
|
||||
|
||||
organization_manager_models = [
|
||||
'access.organization',
|
||||
'access.tenant',
|
||||
'access.team',
|
||||
'access.teamusers',
|
||||
]
|
||||
@ -326,7 +326,7 @@ class OrganizationMixin():
|
||||
|
||||
if required_permission.replace(
|
||||
'view_', ''
|
||||
) == 'access.organization' and len(self.kwargs) == 0:
|
||||
) == 'access.tenant' and len(self.kwargs) == 0:
|
||||
|
||||
return True
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
from django.contrib.auth.models import User, Group
|
||||
import django
|
||||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db import models
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class OrganizationMixin:
|
||||
@ -89,7 +93,7 @@ class OrganizationMixin:
|
||||
|
||||
self._obj_organization = obj.organization
|
||||
|
||||
elif str(self.model._meta.verbose_name).lower() == 'organization':
|
||||
elif str(self.model._meta.verbose_name).lower() == 'tenant':
|
||||
|
||||
self._obj_organization = obj
|
||||
|
||||
@ -130,7 +134,7 @@ class OrganizationMixin:
|
||||
parent_model (Model): with PK from kwargs['pk']
|
||||
"""
|
||||
|
||||
return self.parent_model.objects.get(pk=self.kwargs[self.parent_model_pk_kwarg])
|
||||
return self.get_parent_model().objects.get(pk=self.kwargs[self.parent_model_pk_kwarg])
|
||||
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import exceptions
|
||||
from rest_framework.permissions import DjangoObjectPermissions
|
||||
|
||||
from access.models.tenancy import Organization, TenancyObject
|
||||
from access.models.tenancy import Tenant, TenancyObject
|
||||
|
||||
from core import exceptions as centurion_exceptions
|
||||
|
||||
@ -14,10 +14,10 @@ from core import exceptions as centurion_exceptions
|
||||
class OrganizationPermissionMixin(
|
||||
DjangoObjectPermissions,
|
||||
):
|
||||
"""Organization Permission Mixin
|
||||
"""Tenant Permission Mixin
|
||||
|
||||
This class is to be used as the permission class for API `Views`/`ViewSets`.
|
||||
In combination with the `OrganizationPermissionsMixin`, permission checking
|
||||
In combination with the `TenantPermissionsMixin`, permission checking
|
||||
will be done to ensure the user has the correct permissions to perform the
|
||||
CRUD operation.
|
||||
|
||||
@ -166,7 +166,7 @@ class OrganizationPermissionMixin(
|
||||
raise centurion_exceptions.PermissionDenied()
|
||||
|
||||
|
||||
obj_organization: Organization = view.get_obj_organization(
|
||||
obj_organization: Tenant = view.get_obj_organization(
|
||||
request = request
|
||||
)
|
||||
|
||||
|
@ -1,2 +1,4 @@
|
||||
from . import contact
|
||||
from . import company_base
|
||||
from . import person
|
||||
from . import role
|
||||
|
102
app/access/models/company_base.py
Normal file
102
app/access/models/company_base.py
Normal file
@ -0,0 +1,102 @@
|
||||
from django.db import models
|
||||
|
||||
from access.models.entity import Entity
|
||||
|
||||
|
||||
|
||||
class Company(
|
||||
Entity
|
||||
):
|
||||
# This model is intended to be called `Organization`, however at the time of
|
||||
# creation this was not possible as Tenant (ne Organization) still has
|
||||
# references in code to `organization` witch clashes with the intended name of
|
||||
# this model.
|
||||
|
||||
|
||||
class Meta:
|
||||
|
||||
ordering = [
|
||||
'name',
|
||||
]
|
||||
|
||||
sub_model_type = 'company'
|
||||
|
||||
verbose_name = 'Company'
|
||||
|
||||
verbose_name_plural = 'Companies'
|
||||
|
||||
|
||||
name = models.CharField(
|
||||
blank = False,
|
||||
help_text = 'The name of this entity',
|
||||
max_length = 80,
|
||||
unique = False,
|
||||
verbose_name = 'Name'
|
||||
)
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
||||
return self.name
|
||||
|
||||
|
||||
documentation = ''
|
||||
|
||||
history_model_name = 'company'
|
||||
|
||||
page_layout: dict = [
|
||||
{
|
||||
"name": "Details",
|
||||
"slug": "details",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "double",
|
||||
"left": [
|
||||
'organization',
|
||||
'name',
|
||||
],
|
||||
"right": [
|
||||
'model_notes',
|
||||
'created',
|
||||
'modified',
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Knowledge Base",
|
||||
"slug": "kb_articles",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "knowledge_base",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Tickets",
|
||||
"slug": "tickets",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "tickets",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Notes",
|
||||
"slug": "notes",
|
||||
"sections": []
|
||||
},
|
||||
]
|
||||
|
||||
table_fields: list = [
|
||||
'name',
|
||||
'organization',
|
||||
'created',
|
||||
]
|
||||
|
||||
|
||||
def clean(self):
|
||||
|
||||
super().clean()
|
@ -37,9 +37,9 @@ class Entity(
|
||||
verbose_name = 'ID'
|
||||
)
|
||||
|
||||
|
||||
entity_type = models.CharField(
|
||||
blank = False,
|
||||
default = Meta.verbose_name.lower(),
|
||||
help_text = 'Type this entity is',
|
||||
max_length = 30,
|
||||
unique = False,
|
||||
|
@ -1,155 +1 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from access.fields import (
|
||||
AutoCreatedField,
|
||||
AutoLastModifiedField,
|
||||
AutoSlugField
|
||||
)
|
||||
|
||||
from core.mixin.history_save import SaveHistory
|
||||
|
||||
|
||||
|
||||
class Organization(SaveHistory):
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Organization"
|
||||
verbose_name_plural = "Organizations"
|
||||
ordering = ['name']
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
if self.slug == '_':
|
||||
self.slug = self.name.lower().replace(' ', '_')
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
id = models.AutoField(
|
||||
blank=False,
|
||||
help_text = 'ID of this item',
|
||||
primary_key=True,
|
||||
unique=True,
|
||||
verbose_name = 'ID'
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
blank = False,
|
||||
help_text = 'Name of this Organization',
|
||||
max_length = 50,
|
||||
unique = True,
|
||||
verbose_name = 'Name'
|
||||
)
|
||||
|
||||
manager = models.ForeignKey(
|
||||
User,
|
||||
blank = False,
|
||||
help_text = 'Manager for this organization',
|
||||
null = True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name = 'Manager'
|
||||
)
|
||||
|
||||
model_notes = models.TextField(
|
||||
blank = True,
|
||||
default = None,
|
||||
help_text = 'Tid bits of information',
|
||||
null= True,
|
||||
verbose_name = 'Notes',
|
||||
)
|
||||
|
||||
slug = AutoSlugField()
|
||||
|
||||
created = AutoCreatedField()
|
||||
|
||||
modified = AutoLastModifiedField()
|
||||
|
||||
|
||||
def get_organization(self):
|
||||
return self
|
||||
|
||||
def __int__(self):
|
||||
|
||||
return self.id
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
table_fields: list = [
|
||||
'nbsp',
|
||||
'name',
|
||||
'created',
|
||||
'modified',
|
||||
'nbsp'
|
||||
]
|
||||
|
||||
page_layout: list = [
|
||||
{
|
||||
"name": "Details",
|
||||
"slug": "details",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "double",
|
||||
"left": [
|
||||
'name',
|
||||
'manager',
|
||||
'created',
|
||||
'modified',
|
||||
],
|
||||
"right": [
|
||||
'model_notes',
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Teams",
|
||||
"slug": "teams",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "teams"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Knowledge Base",
|
||||
"slug": "kb_articles",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "knowledge_base",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Notes",
|
||||
"slug": "notes",
|
||||
"sections": []
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def get_url( self, request = None ) -> str:
|
||||
|
||||
if request:
|
||||
|
||||
return reverse("v2:_api_v2_organization-detail", request=request, kwargs={'pk': self.id})
|
||||
|
||||
return reverse("v2:_api_v2_organization-detail", kwargs={'pk': self.id})
|
||||
|
||||
|
||||
def save_history(self, before: dict, after: dict) -> bool:
|
||||
|
||||
from access.models.organization_history import OrganizationHistory
|
||||
|
||||
history = super().save_history(
|
||||
before = before,
|
||||
after = after,
|
||||
history_model = OrganizationHistory
|
||||
)
|
||||
|
||||
|
||||
return history
|
||||
from .tenant import Tenant as Organization
|
||||
|
@ -2,7 +2,7 @@ from django.db import models
|
||||
|
||||
from core.models.model_history import ModelHistory
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ class OrganizationHistory(
|
||||
|
||||
|
||||
model = models.ForeignKey(
|
||||
Organization,
|
||||
Tenant,
|
||||
blank = False,
|
||||
help_text = 'Model this note belongs to',
|
||||
null = False,
|
||||
@ -46,8 +46,8 @@ class OrganizationHistory(
|
||||
|
||||
model = None
|
||||
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
model = OrganizationBaseSerializer(self.model, context = serializer_context)
|
||||
model = TenantBaseSerializer(self.model, context = serializer_context)
|
||||
|
||||
return model
|
||||
|
@ -1,6 +1,6 @@
|
||||
from django.db import models
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
|
||||
from core.models.model_notes import ModelNotes
|
||||
|
||||
@ -23,7 +23,7 @@ class OrganizationNotes(
|
||||
|
||||
|
||||
model = models.ForeignKey(
|
||||
Organization,
|
||||
Tenant,
|
||||
blank = False,
|
||||
help_text = 'Model this note belongs to',
|
||||
null = False,
|
||||
|
@ -36,7 +36,6 @@ class Person(
|
||||
|
||||
m_name = models.CharField(
|
||||
blank = True,
|
||||
default = None,
|
||||
help_text = 'The persons middle name(s)',
|
||||
max_length = 100,
|
||||
null = True,
|
||||
@ -54,7 +53,6 @@ class Person(
|
||||
|
||||
dob = models.DateField(
|
||||
blank = True,
|
||||
default = None,
|
||||
help_text = 'The Persons Date of Birth (DOB)',
|
||||
null = True,
|
||||
unique = False,
|
||||
|
@ -8,7 +8,7 @@ from access.fields import (
|
||||
AutoLastModifiedField
|
||||
)
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
from access.models.tenancy import TenancyObject
|
||||
|
||||
from core import exceptions as centurion_exceptions
|
||||
@ -55,13 +55,13 @@ class Team(Group, TenancyObject):
|
||||
)
|
||||
|
||||
organization = models.ForeignKey(
|
||||
Organization,
|
||||
Tenant,
|
||||
blank = False,
|
||||
help_text = 'Organization this belongs to',
|
||||
help_text = 'Tenant this belongs to',
|
||||
null = False,
|
||||
on_delete = models.CASCADE,
|
||||
validators = [validatate_organization_exists],
|
||||
verbose_name = 'Organization'
|
||||
verbose_name = 'Tenant'
|
||||
)
|
||||
|
||||
created = AutoCreatedField()
|
||||
|
@ -1,6 +1,8 @@
|
||||
import django
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib.auth.models import Group
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
@ -9,12 +11,14 @@ from access.fields import (
|
||||
AutoLastModifiedField
|
||||
)
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
from access.models.team import Team
|
||||
|
||||
from core.lib.feature_not_used import FeatureNotUsed
|
||||
from core.mixin.history_save import SaveHistory
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamUsers(SaveHistory):
|
||||
@ -95,7 +99,7 @@ class TeamUsers(SaveHistory):
|
||||
user.groups.remove(group)
|
||||
|
||||
|
||||
def get_organization(self) -> Organization:
|
||||
def get_organization(self) -> Tenant:
|
||||
return self.team.organization
|
||||
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
# from django.conf import settings
|
||||
import django
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
# from django.contrib.auth.models import User, Group
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
# from .fields import *
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
|
||||
from core import exceptions as centurion_exceptions
|
||||
from core.middleware.get_request import get_request
|
||||
@ -137,14 +136,14 @@ class TenancyObject(SaveHistory):
|
||||
)
|
||||
|
||||
organization = models.ForeignKey(
|
||||
Organization,
|
||||
Tenant,
|
||||
blank = False,
|
||||
help_text = 'Organization this belongs to',
|
||||
help_text = 'Tenancy this belongs to',
|
||||
null = False,
|
||||
on_delete = models.CASCADE,
|
||||
related_name = '+',
|
||||
validators = [validatate_organization_exists],
|
||||
verbose_name = 'Organization'
|
||||
verbose_name = 'Tenant'
|
||||
)
|
||||
|
||||
is_global = models.BooleanField(
|
||||
@ -162,7 +161,7 @@ class TenancyObject(SaveHistory):
|
||||
verbose_name = 'Notes',
|
||||
)
|
||||
|
||||
def get_organization(self) -> Organization:
|
||||
def get_organization(self) -> Tenant:
|
||||
return self.organization
|
||||
|
||||
app_namespace: str = None
|
||||
@ -193,6 +192,16 @@ class TenancyObject(SaveHistory):
|
||||
only be used when there is model inheritence.
|
||||
"""
|
||||
|
||||
_log: logging.Logger = None
|
||||
|
||||
def get_log(self):
|
||||
|
||||
if self._log is None:
|
||||
|
||||
self._log = logging.getLogger('centurion.' + self._meta.app_label)
|
||||
|
||||
return self._log
|
||||
|
||||
page_layout: list = None
|
||||
|
||||
note_basename: str = None
|
||||
@ -282,7 +291,7 @@ class TenancyObject(SaveHistory):
|
||||
|
||||
raise centurion_exceptions.ValidationError(
|
||||
detail = {
|
||||
'organization': 'Organization is required'
|
||||
'organization': 'Tenant is required'
|
||||
},
|
||||
code = 'required'
|
||||
)
|
||||
|
161
app/access/models/tenant.py
Normal file
161
app/access/models/tenant.py
Normal file
@ -0,0 +1,161 @@
|
||||
import django
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from access.fields import (
|
||||
AutoCreatedField,
|
||||
AutoLastModifiedField,
|
||||
AutoSlugField
|
||||
)
|
||||
|
||||
from core.mixin.history_save import SaveHistory
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
class Tenant(SaveHistory):
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Tenant"
|
||||
verbose_name_plural = "Tenants"
|
||||
ordering = ['name']
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
if self.slug == '_':
|
||||
self.slug = self.name.lower().replace(' ', '_')
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
id = models.AutoField(
|
||||
blank=False,
|
||||
help_text = 'ID of this item',
|
||||
primary_key=True,
|
||||
unique=True,
|
||||
verbose_name = 'ID'
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
blank = False,
|
||||
help_text = 'Name of this Tenancy',
|
||||
max_length = 50,
|
||||
unique = True,
|
||||
verbose_name = 'Name'
|
||||
)
|
||||
|
||||
manager = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
blank = False,
|
||||
help_text = 'Manager for this Tenancy',
|
||||
null = True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name = 'Manager'
|
||||
)
|
||||
|
||||
model_notes = models.TextField(
|
||||
blank = True,
|
||||
default = None,
|
||||
help_text = 'Tid bits of information',
|
||||
null= True,
|
||||
verbose_name = 'Notes',
|
||||
)
|
||||
|
||||
slug = AutoSlugField()
|
||||
|
||||
created = AutoCreatedField()
|
||||
|
||||
modified = AutoLastModifiedField()
|
||||
|
||||
|
||||
def get_organization(self):
|
||||
return self
|
||||
|
||||
def __int__(self):
|
||||
|
||||
return self.id
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
table_fields: list = [
|
||||
'nbsp',
|
||||
'name',
|
||||
'created',
|
||||
'modified',
|
||||
'nbsp'
|
||||
]
|
||||
|
||||
page_layout: list = [
|
||||
{
|
||||
"name": "Details",
|
||||
"slug": "details",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "double",
|
||||
"left": [
|
||||
'name',
|
||||
'manager',
|
||||
'created',
|
||||
'modified',
|
||||
],
|
||||
"right": [
|
||||
'model_notes',
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Teams",
|
||||
"slug": "teams",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "teams"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Knowledge Base",
|
||||
"slug": "kb_articles",
|
||||
"sections": [
|
||||
{
|
||||
"layout": "table",
|
||||
"field": "knowledge_base",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Notes",
|
||||
"slug": "notes",
|
||||
"sections": []
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def get_url( self, request = None ) -> str:
|
||||
|
||||
if request:
|
||||
|
||||
return reverse("v2:_api_v2_organization-detail", request=request, kwargs={'pk': self.id})
|
||||
|
||||
return reverse("v2:_api_v2_organization-detail", kwargs={'pk': self.id})
|
||||
|
||||
|
||||
def save_history(self, before: dict, after: dict) -> bool:
|
||||
|
||||
from access.models.organization_history import OrganizationHistory
|
||||
|
||||
history = super().save_history(
|
||||
before = before,
|
||||
after = after,
|
||||
history_model = OrganizationHistory
|
||||
)
|
||||
|
||||
|
||||
return history
|
||||
|
||||
|
||||
|
||||
Organization = Tenant
|
@ -6,7 +6,7 @@ from access.models.entity import Entity
|
||||
|
||||
from api.serializers import common
|
||||
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
|
||||
|
||||
@ -87,4 +87,4 @@ class ModelSerializer(
|
||||
class ViewSerializer(ModelSerializer):
|
||||
"""Entity Base View Model"""
|
||||
|
||||
organization = OrganizationBaseSerializer(many=False, read_only=True)
|
||||
organization = TenantBaseSerializer(many=False, read_only=True)
|
||||
|
70
app/access/serializers/entity_company.py
Normal file
70
app/access/serializers/entity_company.py
Normal file
@ -0,0 +1,70 @@
|
||||
from drf_spectacular.utils import extend_schema_serializer
|
||||
|
||||
from access.models.company_base import Company
|
||||
|
||||
from access.serializers.entity import (
|
||||
BaseSerializer as BaseBaseSerializer,
|
||||
ModelSerializer as BaseModelSerializer,
|
||||
)
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
|
||||
|
||||
class BaseSerializer(
|
||||
BaseBaseSerializer,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@extend_schema_serializer(component_name = 'CompanyEntityModelSerializer')
|
||||
class ModelSerializer(
|
||||
BaseSerializer,
|
||||
BaseModelSerializer,
|
||||
):
|
||||
"""Company Model
|
||||
|
||||
This model inherits from the Entity base model.
|
||||
"""
|
||||
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Company
|
||||
|
||||
fields = [
|
||||
'id',
|
||||
'entity_ptr_id',
|
||||
'organization',
|
||||
'entity_type',
|
||||
'display_name',
|
||||
'name',
|
||||
'model_notes',
|
||||
'is_global',
|
||||
'created',
|
||||
'modified',
|
||||
'_urls',
|
||||
]
|
||||
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'display_name',
|
||||
'entity_type',
|
||||
'created',
|
||||
'modified',
|
||||
'_urls',
|
||||
]
|
||||
|
||||
|
||||
|
||||
@extend_schema_serializer(component_name = 'CompanyEntityViewSerializer')
|
||||
class ViewSerializer(
|
||||
ModelSerializer,
|
||||
):
|
||||
"""Company View Model
|
||||
|
||||
This model inherits from the Entity base model.
|
||||
"""
|
||||
|
||||
organization = TenantBaseSerializer(many=False, read_only=True)
|
@ -6,7 +6,7 @@ from access.serializers.entity_person import (
|
||||
BaseSerializer as BaseBaseSerializer,
|
||||
ModelSerializer as BaseModelSerializer,
|
||||
)
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
|
||||
|
||||
@ -72,4 +72,4 @@ class ViewSerializer(
|
||||
This model inherits from the Person model.
|
||||
"""
|
||||
|
||||
organization = OrganizationBaseSerializer(many=False, read_only=True)
|
||||
organization = TenantBaseSerializer(many=False, read_only=True)
|
||||
|
@ -6,7 +6,7 @@ from access.serializers.entity import (
|
||||
BaseSerializer as BaseBaseSerializer,
|
||||
ModelSerializer as BaseModelSerializer,
|
||||
)
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
|
||||
|
||||
@ -70,4 +70,4 @@ class ViewSerializer(
|
||||
This model inherits from the Entity base model.
|
||||
"""
|
||||
|
||||
organization = OrganizationBaseSerializer(many=False, read_only=True)
|
||||
organization = TenantBaseSerializer(many=False, read_only=True)
|
||||
|
@ -2,15 +2,16 @@ from rest_framework.reverse import reverse
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
|
||||
from app.serializers.user import UserBaseSerializer
|
||||
|
||||
from core import fields as centurion_field
|
||||
|
||||
Organization = Tenant
|
||||
|
||||
|
||||
class OrganizationBaseSerializer(serializers.ModelSerializer):
|
||||
class TenantBaseSerializer(serializers.ModelSerializer):
|
||||
|
||||
display_name = serializers.SerializerMethodField('get_display_name')
|
||||
|
||||
@ -24,7 +25,7 @@ class OrganizationBaseSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Organization
|
||||
model = Tenant
|
||||
|
||||
fields = [
|
||||
'id',
|
||||
@ -42,8 +43,8 @@ class OrganizationBaseSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
|
||||
class OrganizationModelSerializer(
|
||||
OrganizationBaseSerializer
|
||||
class TenantModelSerializer(
|
||||
TenantBaseSerializer
|
||||
):
|
||||
|
||||
_urls = serializers.SerializerMethodField('get_url')
|
||||
@ -74,7 +75,7 @@ class OrganizationModelSerializer(
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Organization
|
||||
model = Tenant
|
||||
|
||||
fields = '__all__'
|
||||
|
||||
@ -98,7 +99,7 @@ class OrganizationModelSerializer(
|
||||
]
|
||||
|
||||
|
||||
class OrganizationViewSerializer(OrganizationModelSerializer):
|
||||
class TenantViewSerializer(TenantModelSerializer):
|
||||
pass
|
||||
|
||||
manager = UserBaseSerializer(many=False, read_only = True)
|
||||
|
@ -5,7 +5,7 @@ from drf_spectacular.utils import extend_schema_serializer
|
||||
|
||||
from access.functions.permissions import permission_queryset
|
||||
from access.models.role import Role
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
from api.serializers import common
|
||||
|
||||
@ -109,6 +109,6 @@ class ModelSerializer(
|
||||
class ViewSerializer(ModelSerializer):
|
||||
"""Role Base View Model"""
|
||||
|
||||
organization = OrganizationBaseSerializer( many=False, read_only=True )
|
||||
organization = TenantBaseSerializer( many=False, read_only=True )
|
||||
|
||||
permissions = PermissionBaseSerializer( many=True, read_only=True )
|
||||
|
@ -7,7 +7,7 @@ from access.models.team import Team
|
||||
from api.serializers import common
|
||||
|
||||
from access.functions.permissions import permission_queryset
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
from access.serializers.organization import TenantBaseSerializer
|
||||
|
||||
from app.serializers.permission import Permission, PermissionBaseSerializer
|
||||
|
||||
@ -127,6 +127,6 @@ class TeamModelSerializer(
|
||||
|
||||
class TeamViewSerializer(TeamModelSerializer):
|
||||
|
||||
organization = OrganizationBaseSerializer(many=False, read_only=True)
|
||||
organization = TenantBaseSerializer(many=False, read_only=True)
|
||||
|
||||
permissions = PermissionBaseSerializer(many = True)
|
||||
|
24
app/access/tests/functional/company/conftest.py
Normal file
24
app/access/tests/functional/company/conftest.py
Normal file
@ -0,0 +1,24 @@
|
||||
import pytest
|
||||
|
||||
from access.models.company_base import Company
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Company
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def create_serializer():
|
||||
|
||||
from access.serializers.entity_company import ModelSerializer
|
||||
|
||||
|
||||
yield ModelSerializer
|
@ -0,0 +1,72 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.company_base import Company
|
||||
from access.tests.functional.entity.test_functional_entity_metadata import (
|
||||
EntityMetadataInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CompanyMetadataTestCases(
|
||||
EntityMetadataInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'name': 'Ian1'
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'name': 'Ian2',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'name': 'Ian3',
|
||||
}
|
||||
|
||||
model = Company
|
||||
|
||||
|
||||
|
||||
|
||||
class CompanyMetadataInheritedCases(
|
||||
CompanyMetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
# self.url_kwargs = {
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# }
|
||||
|
||||
# self.url_view_kwargs = {
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# }
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class CompanyMetadataTest(
|
||||
CompanyMetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
pass
|
@ -0,0 +1,43 @@
|
||||
import pytest
|
||||
|
||||
from access.tests.functional.entity.test_functional_entity_permission import (
|
||||
EntityPermissionsAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CompanyPermissionsAPITestCases(
|
||||
EntityPermissionsAPIInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'name': 'Ian1',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'name': 'Ian2',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'name': 'Ian3',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CompanyPermissionsAPIInheritedCases(
|
||||
CompanyPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
|
||||
class CompanyPermissionsAPIPyTest(
|
||||
CompanyPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -0,0 +1,46 @@
|
||||
import pytest
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.tests.functional.entity.test_functional_entity_serializer import (
|
||||
MockView,
|
||||
EntitySerializerInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CompanySerializerTestCases(
|
||||
EntitySerializerInheritedCases
|
||||
):
|
||||
|
||||
|
||||
parameterized_test_data: dict = {
|
||||
"name": {
|
||||
'will_create': False,
|
||||
'exception_key': 'required'
|
||||
},
|
||||
}
|
||||
|
||||
valid_data: dict = {
|
||||
'name': 'Ian',
|
||||
}
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
|
||||
class CompanySerializerInheritedCases(
|
||||
CompanySerializerTestCases,
|
||||
):
|
||||
|
||||
parameterized_test_data: dict = None
|
||||
|
||||
valid_data: dict = None
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
|
||||
class CompanySerializerPyTest(
|
||||
CompanySerializerTestCases,
|
||||
):
|
||||
|
||||
parameterized_test_data: dict = None
|
@ -0,0 +1,58 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.company_base import Company
|
||||
from access.tests.functional.entity.test_functional_entity_viewset import (
|
||||
EntityViewSetInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ViewSetTestCases(
|
||||
EntityViewSetInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'name': 'Ian',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'name': 'Ian2',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'name': 'Ian3',
|
||||
}
|
||||
|
||||
model = Company
|
||||
|
||||
|
||||
|
||||
class CompanyViewSetInheritedCases(
|
||||
ViewSetTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class CompanyViewSetTest(
|
||||
ViewSetTestCases,
|
||||
TestCase,
|
||||
):
|
||||
pass
|
24
app/access/tests/functional/contact/conftest.py
Normal file
24
app/access/tests/functional/contact/conftest.py
Normal file
@ -0,0 +1,24 @@
|
||||
import pytest
|
||||
|
||||
from access.models.contact import Contact
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Contact
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def create_serializer():
|
||||
|
||||
from access.serializers.entity_contact import ModelSerializer
|
||||
|
||||
|
||||
yield ModelSerializer
|
@ -0,0 +1,65 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.contact import Contact
|
||||
|
||||
from access.tests.functional.person.test_functional_person_metadata import (
|
||||
PersonMetadataInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ContactMetadataTestCases(
|
||||
PersonMetadataInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipweird@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'email': 'ipstrange@unit.test',
|
||||
}
|
||||
|
||||
model = Contact
|
||||
|
||||
|
||||
|
||||
|
||||
class ContactMetadataInheritedCases(
|
||||
ContactMetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class ContactMetadataTest(
|
||||
ContactMetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
pass
|
@ -0,0 +1,70 @@
|
||||
import pytest
|
||||
|
||||
from access.tests.functional.person.test_functional_person_permission import (
|
||||
PersonPermissionsAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ContactPermissionsAPITestCases(
|
||||
PersonPermissionsAPIInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipweird@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'email': 'ipstrange@unit.test',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ContactPermissionsAPIInheritedCases(
|
||||
ContactPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
# url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
# @pytest.fixture(scope='class')
|
||||
# def inherited_var_setup(self, request):
|
||||
|
||||
# request.cls.url_kwargs.update({
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# })
|
||||
|
||||
# request.cls.url_view_kwargs.update({
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# })
|
||||
|
||||
|
||||
|
||||
# @pytest.fixture(scope='class', autouse = True)
|
||||
# def class_setup(self, request, django_db_blocker,
|
||||
# model,
|
||||
# var_setup,
|
||||
# prepare,
|
||||
# inherited_var_setup,
|
||||
# diff_org_model,
|
||||
# create_model,
|
||||
# ):
|
||||
|
||||
# pass
|
||||
|
||||
|
||||
class ContactPermissionsAPIPyTest(
|
||||
ContactPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,129 +1,46 @@
|
||||
import pytest
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.serializers.entity_contact import (
|
||||
Contact,
|
||||
ModelSerializer
|
||||
)
|
||||
from access.tests.functional.person.test_functional_person_serializer import (
|
||||
MockView,
|
||||
PersonSerializerInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SerializerTestCases(
|
||||
PersonSerializerInheritedCases,
|
||||
class ContactSerializerTestCases(
|
||||
PersonSerializerInheritedCases
|
||||
):
|
||||
|
||||
duplicate_f_name_l_name_dob = {
|
||||
'email': 'contactentityduplicateone@unit.test',
|
||||
|
||||
parameterized_test_data: dict = {
|
||||
"email": {
|
||||
'will_create': False,
|
||||
'exception_key': 'required'
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item_duplicate_f_name_l_name_dob = {
|
||||
'email': 'contactentityduplicatetwo@unit.test',
|
||||
}
|
||||
|
||||
model = Contact
|
||||
"""Model to test"""
|
||||
|
||||
create_model_serializer = ModelSerializer
|
||||
"""Serializer to test"""
|
||||
|
||||
valid_data: dict = {
|
||||
'email': 'ipweird@unit.test',
|
||||
'email': 'contactentityduplicatetwo@unit.test',
|
||||
}
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_no_email_exception(self):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and field email is missing
|
||||
a validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['email']
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
serializer.is_valid(raise_exception = True)
|
||||
|
||||
assert err.value.get_codes()['email'][0] == 'required'
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
|
||||
class ContactSerializerInheritedCases(
|
||||
SerializerTestCases,
|
||||
ContactSerializerTestCases,
|
||||
):
|
||||
|
||||
create_model_serializer = None
|
||||
"""Serializer to test"""
|
||||
|
||||
duplicate_f_name_l_name_dob: dict = None
|
||||
""" Duplicate model serializer dict
|
||||
|
||||
used for testing for duplicate f_name, l_name and dob fields.
|
||||
"""
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
""" Model kwargs to create item"""
|
||||
|
||||
kwargs_create_item_duplicate_f_name_l_name_dob: dict = None
|
||||
"""model kwargs to create object
|
||||
|
||||
**None:** Ensure that the fields of sub-model to person do not match
|
||||
`self.duplicate_f_name_l_name_dob`. if they do the wrong exception will be thrown.
|
||||
|
||||
used for testing for duplicate f_name, l_name and dob fields.
|
||||
"""
|
||||
|
||||
model = None
|
||||
"""Model to test"""
|
||||
parameterized_test_data: dict = None
|
||||
|
||||
valid_data: dict = None
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test"""
|
||||
|
||||
self.duplicate_f_name_l_name_dob.update(
|
||||
super().duplicate_f_name_l_name_dob
|
||||
)
|
||||
|
||||
self.kwargs_create_item_duplicate_f_name_l_name_dob.update(
|
||||
super().kwargs_create_item_duplicate_f_name_l_name_dob
|
||||
)
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.valid_data.update(
|
||||
super().valid_data
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class ContactSerializerTest(
|
||||
SerializerTestCases,
|
||||
TestCase,
|
||||
class ContactSerializerPyTest(
|
||||
ContactSerializerTestCases,
|
||||
):
|
||||
|
||||
pass
|
||||
parameterized_test_data: dict = None
|
||||
|
@ -2,91 +2,28 @@ from django.test import TestCase
|
||||
|
||||
from access.models.contact import Contact
|
||||
from access.tests.functional.person.test_functional_person_viewset import (
|
||||
PersonMetadataInheritedCases,
|
||||
PersonPermissionsAPIInheritedCases,
|
||||
PersonViewSetInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
|
||||
add_data = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org = {
|
||||
'email': 'ipstrange@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item = {
|
||||
'email': 'ipweird@unit.test',
|
||||
}
|
||||
|
||||
model = Contact
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
|
||||
|
||||
class PermissionsAPITestCases(
|
||||
ViewSetBase,
|
||||
PersonPermissionsAPIInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ContactPermissionsAPIInheritedCases(
|
||||
PermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.add_data.update(
|
||||
super().add_data
|
||||
)
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class ContactPermissionsAPITest(
|
||||
PermissionsAPITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ViewSetTestCases(
|
||||
ViewSetBase,
|
||||
PersonViewSetInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
add_data: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipweird@unit.test',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'email': 'ipstrange@unit.test',
|
||||
}
|
||||
|
||||
model = Contact
|
||||
|
||||
|
||||
|
||||
@ -96,21 +33,19 @@ class ContactViewSetInheritedCases(
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
@ -120,50 +55,4 @@ class ContactViewSetTest(
|
||||
ViewSetTestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class MetadataTestCases(
|
||||
ViewSetBase,
|
||||
PersonMetadataInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ContactMetadataInheritedCases(
|
||||
MetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class ContactMetadataTest(
|
||||
MetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
|
||||
pass
|
||||
|
24
app/access/tests/functional/entity/conftest.py
Normal file
24
app/access/tests/functional/entity/conftest.py
Normal file
@ -0,0 +1,24 @@
|
||||
import pytest
|
||||
|
||||
from access.models.entity import Entity
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Entity
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def create_serializer():
|
||||
|
||||
from access.serializers.entity import ModelSerializer
|
||||
|
||||
|
||||
yield ModelSerializer
|
@ -0,0 +1,260 @@
|
||||
import django
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.entity import Entity
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from accounting.models.asset_base import AssetBase
|
||||
|
||||
from api.tests.abstract.test_metadata_functional import MetadataAttributesFunctional
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class EntityMetadataTestCases(
|
||||
MetadataAttributesFunctional,
|
||||
):
|
||||
|
||||
add_data: dict = {}
|
||||
|
||||
app_namespace = 'v2'
|
||||
|
||||
base_model = Entity
|
||||
"""Base model for this sub model
|
||||
don't change or override this value
|
||||
"""
|
||||
|
||||
change_data = None
|
||||
|
||||
delete_data = {}
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
model = Entity
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
url_name = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test
|
||||
|
||||
1. Create an organization for user and item
|
||||
. create an organization that is different to item
|
||||
2. Create a team
|
||||
3. create teams with each permission: view, add, change, delete
|
||||
4. create a user per team
|
||||
"""
|
||||
|
||||
organization = Organization.objects.create(name='test_org')
|
||||
|
||||
self.organization = organization
|
||||
|
||||
self.different_organization = Organization.objects.create(name='test_different_organization')
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization = organization,
|
||||
**self.kwargs_create_item
|
||||
)
|
||||
|
||||
self.other_org_item = self.model.objects.create(
|
||||
organization = self.different_organization,
|
||||
**self.kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
|
||||
self.url_view_kwargs.update({ 'pk': self.item.id })
|
||||
|
||||
if self.add_data is not None:
|
||||
|
||||
self.add_data.update({
|
||||
'organization': self.organization.id,
|
||||
})
|
||||
|
||||
|
||||
view_permissions = Permission.objects.get(
|
||||
codename = 'view_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
view_team = Team.objects.create(
|
||||
team_name = 'view_team',
|
||||
organization = organization,
|
||||
)
|
||||
|
||||
view_team.permissions.set([view_permissions])
|
||||
|
||||
|
||||
|
||||
add_permissions = Permission.objects.get(
|
||||
codename = 'add_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
add_team = Team.objects.create(
|
||||
team_name = 'add_team',
|
||||
organization = organization,
|
||||
)
|
||||
|
||||
add_team.permissions.set([add_permissions])
|
||||
|
||||
|
||||
|
||||
change_permissions = Permission.objects.get(
|
||||
codename = 'change_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
change_team = Team.objects.create(
|
||||
team_name = 'change_team',
|
||||
organization = organization,
|
||||
)
|
||||
|
||||
change_team.permissions.set([change_permissions])
|
||||
|
||||
|
||||
|
||||
delete_permissions = Permission.objects.get(
|
||||
codename = 'delete_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
delete_team = Team.objects.create(
|
||||
team_name = 'delete_team',
|
||||
organization = organization,
|
||||
)
|
||||
|
||||
delete_team.permissions.set([delete_permissions])
|
||||
|
||||
|
||||
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
|
||||
|
||||
|
||||
TeamUsers.objects.create(
|
||||
team = view_team,
|
||||
user = self.view_user
|
||||
)
|
||||
|
||||
self.add_user = User.objects.create_user(username="test_user_add", password="password")
|
||||
TeamUsers.objects.create(
|
||||
team = add_team,
|
||||
user = self.add_user
|
||||
)
|
||||
|
||||
self.change_user = User.objects.create_user(username="test_user_change", password="password")
|
||||
TeamUsers.objects.create(
|
||||
team = change_team,
|
||||
user = self.change_user
|
||||
)
|
||||
|
||||
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
|
||||
TeamUsers.objects.create(
|
||||
team = delete_team,
|
||||
user = self.delete_user
|
||||
)
|
||||
|
||||
|
||||
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
|
||||
|
||||
|
||||
different_organization_team = Team.objects.create(
|
||||
team_name = 'different_organization_team',
|
||||
organization = self.different_organization,
|
||||
)
|
||||
|
||||
different_organization_team.permissions.set([
|
||||
view_permissions,
|
||||
add_permissions,
|
||||
change_permissions,
|
||||
delete_permissions,
|
||||
])
|
||||
|
||||
TeamUsers.objects.create(
|
||||
team = different_organization_team,
|
||||
user = self.different_organization_user
|
||||
)
|
||||
|
||||
|
||||
def test_sanity_is_entity_sub_model(self):
|
||||
"""Sanity Test
|
||||
|
||||
This test ensures that the model being tested `self.model` is a
|
||||
sub-model of `self.base_model`.
|
||||
This test is required as the same viewset is used for all sub-models
|
||||
of `AssetBase`
|
||||
"""
|
||||
|
||||
assert issubclass(self.model, self.base_model)
|
||||
|
||||
|
||||
|
||||
class EntityMetadataInheritedCases(
|
||||
EntityMetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
self.url_kwargs = {
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
}
|
||||
|
||||
self.url_view_kwargs = {
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class EntityMetadataTest(
|
||||
EntityMetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
|
||||
url_name = '_api_v2_entity'
|
@ -0,0 +1,89 @@
|
||||
import pytest
|
||||
|
||||
from api.tests.functional.test_functional_api_permissions import (
|
||||
APIPermissionsInheritedCases,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class EntityPermissionsAPITestCases(
|
||||
APIPermissionsInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {}
|
||||
|
||||
app_namespace = 'v2'
|
||||
|
||||
change_data = {}
|
||||
|
||||
delete_data = {}
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_name = '_api_v2_entity'
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
|
||||
|
||||
def test_returned_data_from_user_and_global_organizations_only(self):
|
||||
"""Check items returned
|
||||
|
||||
This test case is a over-ride of a test case with the same name.
|
||||
This model is not a tenancy model making this test not-applicable.
|
||||
|
||||
Items returned from the query Must be from the users organization and
|
||||
global ONLY!
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class EntityPermissionsAPIInheritedCases(
|
||||
EntityPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def inherited_var_setup(self, request):
|
||||
|
||||
request.cls.url_kwargs.update({
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
})
|
||||
|
||||
request.cls.url_view_kwargs.update({
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
})
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope='class', autouse = True)
|
||||
def class_setup(self, request, django_db_blocker,
|
||||
model,
|
||||
var_setup,
|
||||
prepare,
|
||||
inherited_var_setup,
|
||||
diff_org_model,
|
||||
create_model,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class EntityPermissionsAPIPyTest(
|
||||
EntityPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,94 +1,171 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.test import TestCase
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.serializers.entity import (
|
||||
Entity,
|
||||
ModelSerializer
|
||||
)
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class SerializerTestCases:
|
||||
class MockView:
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
""" Model kwargs to create item"""
|
||||
_has_import: bool = False
|
||||
"""User Permission
|
||||
|
||||
model = Entity
|
||||
"""Model to test"""
|
||||
get_permission_required() sets this to `True` when user has import permission.
|
||||
"""
|
||||
|
||||
create_model_serializer = ModelSerializer
|
||||
"""Serializer to test"""
|
||||
_has_purge: bool = False
|
||||
"""User Permission
|
||||
|
||||
valid_data: dict = {}
|
||||
get_permission_required() sets this to `True` when user has purge permission.
|
||||
"""
|
||||
|
||||
_has_triage: bool = False
|
||||
"""User Permission
|
||||
|
||||
get_permission_required() sets this to `True` when user has triage permission.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class EntitySerializerTestCases:
|
||||
|
||||
|
||||
parameterized_test_data: dict = {
|
||||
"model_notes": {
|
||||
'will_create': True,
|
||||
}
|
||||
}
|
||||
|
||||
valid_data: dict = {
|
||||
'model_notes': 'model notes field'
|
||||
}
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test"""
|
||||
|
||||
self.organization = Organization.objects.create(name='test_org')
|
||||
|
||||
self.kwargs_create_item.update({
|
||||
'model_notes': 'model notes field'
|
||||
})
|
||||
@pytest.fixture( scope = 'class')
|
||||
def setup_data(self,
|
||||
request,
|
||||
model,
|
||||
django_db_blocker,
|
||||
organization_one,
|
||||
):
|
||||
|
||||
self.valid_data.update({
|
||||
'organization': self.organization.pk,
|
||||
'model_notes': 'model notes field'
|
||||
})
|
||||
with django_db_blocker.unblock():
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization = self.organization,
|
||||
**self.kwargs_create_item,
|
||||
)
|
||||
request.cls.organization = organization_one
|
||||
|
||||
valid_data = {}
|
||||
|
||||
for base in reversed(request.cls.__mro__):
|
||||
|
||||
if hasattr(base, 'valid_data'):
|
||||
|
||||
if base.valid_data is None:
|
||||
|
||||
continue
|
||||
|
||||
valid_data.update(**base.valid_data)
|
||||
|
||||
|
||||
if len(valid_data) > 0:
|
||||
|
||||
request.cls.valid_data = valid_data
|
||||
|
||||
|
||||
if 'organization' not in request.cls.valid_data:
|
||||
|
||||
request.cls.valid_data.update({
|
||||
'organization': request.cls.organization.pk
|
||||
})
|
||||
|
||||
|
||||
request.cls.view_user = User.objects.create_user(username="cafs_test_user_view", password="password")
|
||||
|
||||
|
||||
yield
|
||||
|
||||
with django_db_blocker.unblock():
|
||||
|
||||
request.cls.view_user.delete()
|
||||
|
||||
del request.cls.valid_data
|
||||
|
||||
|
||||
|
||||
def test_serializer_valid_data(self):
|
||||
@pytest.fixture( scope = 'class', autouse = True)
|
||||
def class_setup(self,
|
||||
setup_data,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def test_serializer_valid_data(self, create_serializer):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating an object with valid data, no validation
|
||||
error occurs.
|
||||
"""
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
view_set = MockView()
|
||||
|
||||
serializer = create_serializer(
|
||||
context = {
|
||||
'view': view_set,
|
||||
},
|
||||
data = self.valid_data
|
||||
)
|
||||
|
||||
assert serializer.is_valid(raise_exception = True)
|
||||
|
||||
|
||||
def test_serializer_validation_no_model_notes(self):
|
||||
|
||||
def test_serializer_valid_data_missing_field_is_valid(self, parameterized, param_key_test_data,
|
||||
create_serializer,
|
||||
param_value,
|
||||
param_will_create,
|
||||
):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that if creating and no model_notes is provided no validation
|
||||
error occurs
|
||||
Ensure that when creating an object with a user with import permission
|
||||
and with valid data, no validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['model_notes']
|
||||
valid_data = self.valid_data.copy()
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
del valid_data[param_value]
|
||||
|
||||
view_set = MockView()
|
||||
|
||||
view_set._has_import = True
|
||||
|
||||
serializer = create_serializer(
|
||||
context = {
|
||||
'view': view_set,
|
||||
},
|
||||
data = valid_data
|
||||
)
|
||||
|
||||
assert serializer.is_valid(raise_exception = True)
|
||||
is_valid = serializer.is_valid(raise_exception = False)
|
||||
|
||||
assert (
|
||||
(
|
||||
not param_will_create
|
||||
and param_will_create == is_valid
|
||||
)
|
||||
or param_will_create == is_valid
|
||||
)
|
||||
|
||||
|
||||
|
||||
class EntitySerializerInheritedCases(
|
||||
SerializerTestCases,
|
||||
EntitySerializerTestCases,
|
||||
):
|
||||
|
||||
create_model_serializer = None
|
||||
"""Serializer to test"""
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
""" Model kwargs to create item"""
|
||||
parameterized_test_data: dict = None
|
||||
|
||||
model = None
|
||||
"""Model to test"""
|
||||
@ -97,10 +174,40 @@ class EntitySerializerInheritedCases(
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
def test_serializer_valid_data_missing_field_raises_exception(self, parameterized, param_key_test_data,
|
||||
create_serializer,
|
||||
param_value,
|
||||
param_exception_key,
|
||||
):
|
||||
"""Serializer Validation Check
|
||||
|
||||
class EntitySerializerTest(
|
||||
SerializerTestCases,
|
||||
TestCase,
|
||||
Ensure that when creating an object with a user with import permission
|
||||
and with valid data, no validation error occurs.
|
||||
"""
|
||||
|
||||
valid_data = self.valid_data.copy()
|
||||
|
||||
del valid_data[param_value]
|
||||
|
||||
view_set = MockView()
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = create_serializer(
|
||||
context = {
|
||||
'view': view_set,
|
||||
},
|
||||
data = valid_data
|
||||
)
|
||||
|
||||
is_valid = serializer.is_valid(raise_exception = True)
|
||||
|
||||
assert err.value.get_codes()[param_value][0] == param_exception_key
|
||||
|
||||
|
||||
|
||||
class EntitySerializerPyTest(
|
||||
EntitySerializerTestCases,
|
||||
):
|
||||
|
||||
pass
|
||||
parameterized_test_data: dict = None
|
||||
|
@ -1,37 +1,49 @@
|
||||
from django.contrib.auth.models import Permission, User
|
||||
import django
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.entity import Entity
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.test_metadata_functional import MetadataAttributesFunctional
|
||||
from api.tests.abstract.api_permissions_viewset import APIPermissions
|
||||
from api.tests.abstract.api_serializer_viewset import SerializersTestCases
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
|
||||
add_data: dict = None
|
||||
add_data: dict = {
|
||||
'model_notes': 'added model note'
|
||||
}
|
||||
|
||||
app_namespace = 'v2'
|
||||
|
||||
base_model = Entity
|
||||
"""Base model for this sub model
|
||||
don't change or override this value
|
||||
"""
|
||||
|
||||
change_data = None
|
||||
|
||||
delete_data = {}
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
kwargs_create_item: dict = {
|
||||
'model_notes': 'added model note'
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'model_notes': 'added model note'
|
||||
}
|
||||
|
||||
model = None
|
||||
|
||||
url_kwargs: dict = None
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = None
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
url_name = None
|
||||
|
||||
@ -53,16 +65,15 @@ class ViewSetBase:
|
||||
|
||||
self.different_organization = Organization.objects.create(name='test_different_organization')
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization = organization,
|
||||
model_notes = 'some notes',
|
||||
**self.kwargs_create_item
|
||||
)
|
||||
|
||||
self.other_org_item = self.model.objects.create(
|
||||
organization = self.different_organization,
|
||||
model_notes = 'some more notes',
|
||||
**self.kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
@ -71,7 +82,9 @@ class ViewSetBase:
|
||||
|
||||
if self.add_data is not None:
|
||||
|
||||
self.add_data.update({'organization': self.organization.id})
|
||||
self.add_data.update({
|
||||
'organization': self.organization.id,
|
||||
})
|
||||
|
||||
|
||||
view_permissions = Permission.objects.get(
|
||||
@ -144,7 +157,6 @@ class ViewSetBase:
|
||||
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
|
||||
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
TeamUsers.objects.create(
|
||||
team = view_team,
|
||||
user = self.view_user
|
||||
@ -190,98 +202,16 @@ class ViewSetBase:
|
||||
)
|
||||
|
||||
|
||||
|
||||
class PermissionsAPITestCases(
|
||||
ViewSetBase,
|
||||
APIPermissions,
|
||||
):
|
||||
|
||||
|
||||
add_data: dict = {}
|
||||
|
||||
change_data = {'model_notes': 'device'}
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
url_kwargs: dict = None
|
||||
|
||||
url_view_kwargs: dict = None
|
||||
|
||||
url_name = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.add_data.update({ 'model_note': 'added model note' })
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
def test_returned_data_from_user_and_global_organizations_only(self):
|
||||
"""Check items returned
|
||||
|
||||
This test case is a over-ride of a test case with the same name.
|
||||
This model is not a tenancy model making this test not-applicable.
|
||||
|
||||
Items returned from the query Must be from the users organization and
|
||||
global ONLY!
|
||||
def test_sanity_is_asset_sub_model(self):
|
||||
"""Sanity Test
|
||||
|
||||
This test ensures that the model being tested `self.model` is a
|
||||
sub-model of `self.base_model`.
|
||||
This test is required as the same viewset is used for all sub-models
|
||||
of `Entity`
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class EntityPermissionsAPIInheritedCases(
|
||||
PermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.url_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
}
|
||||
|
||||
self.url_view_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class EntityPermissionsAPITest(
|
||||
PermissionsAPITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
model = Entity
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
url_name = '_api_v2_entity'
|
||||
|
||||
assert issubclass(self.model, self.base_model)
|
||||
|
||||
|
||||
|
||||
@ -290,17 +220,7 @@ class ViewSetTestCases(
|
||||
SerializersTestCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
url_kwargs: dict = None
|
||||
|
||||
url_view_kwargs: dict = None
|
||||
|
||||
url_name = None
|
||||
model = Entity
|
||||
|
||||
|
||||
|
||||
@ -310,22 +230,28 @@ class EntityViewSetInheritedCases(
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
self.url_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
}
|
||||
|
||||
self.url_view_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
'entity_model': self.model._meta.sub_model_type
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
@ -337,168 +263,4 @@ class EntityViewSetTest(
|
||||
TestCase,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
model = Entity
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
url_name = '_api_v2_entity'
|
||||
|
||||
|
||||
|
||||
class MetadataTestCases(
|
||||
ViewSetBase,
|
||||
MetadataAttributesFunctional,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
url_kwargs: dict = None
|
||||
|
||||
url_view_kwargs: dict = None
|
||||
|
||||
url_name = None
|
||||
|
||||
|
||||
|
||||
class EntityMetadataInheritedCases(
|
||||
MetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.url_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
}
|
||||
|
||||
self.url_view_kwargs = {
|
||||
'entity_model': self.model._meta.model_name
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class EntityMetadataTest(
|
||||
MetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
model = Entity
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
url_name = '_api_v2_entity'
|
||||
|
||||
|
||||
# def test_method_options_request_detail_data_has_key_urls_back(self):
|
||||
# """Test HTTP/Options Method
|
||||
|
||||
# Ensure the request data returned has key `urls.back`
|
||||
# """
|
||||
|
||||
# client = Client()
|
||||
# client.force_login(self.view_user)
|
||||
|
||||
# response = client.options(
|
||||
# reverse(
|
||||
# self.app_namespace + ':' + self.url_name + '-detail',
|
||||
# kwargs=self.url_view_kwargs
|
||||
# ),
|
||||
# content_type='application/json'
|
||||
# )
|
||||
|
||||
# assert 'back' in response.data['urls']
|
||||
|
||||
|
||||
# def test_method_options_request_detail_data_key_urls_back_is_str(self):
|
||||
# """Test HTTP/Options Method
|
||||
|
||||
# Ensure the request data key `urls.back` is str
|
||||
# """
|
||||
|
||||
# client = Client()
|
||||
# client.force_login(self.view_user)
|
||||
|
||||
# response = client.options(
|
||||
# reverse(
|
||||
# self.app_namespace + ':' + self.url_name + '-detail',
|
||||
# kwargs=self.url_view_kwargs
|
||||
# ),
|
||||
# content_type='application/json'
|
||||
# )
|
||||
|
||||
# assert type(response.data['urls']['back']) is str
|
||||
|
||||
|
||||
|
||||
# def test_method_options_request_list_data_has_key_urls_return_url(self):
|
||||
# """Test HTTP/Options Method
|
||||
|
||||
# Ensure the request data returned has key `urls.return_url`
|
||||
# """
|
||||
|
||||
# client = Client()
|
||||
# client.force_login(self.view_user)
|
||||
|
||||
# if self.url_kwargs:
|
||||
|
||||
# url = reverse(self.app_namespace + ':' + self.url_name + '-list', kwargs = self.url_kwargs)
|
||||
|
||||
# else:
|
||||
|
||||
# url = reverse(self.app_namespace + ':' + self.url_name + '-list')
|
||||
|
||||
# response = client.options( url, content_type='application/json' )
|
||||
|
||||
# assert 'return_url' in response.data['urls']
|
||||
|
||||
|
||||
# def test_method_options_request_list_data_key_urls_return_url_is_str(self):
|
||||
# """Test HTTP/Options Method
|
||||
|
||||
# Ensure the request data key `urls.return_url` is str
|
||||
# """
|
||||
|
||||
# client = Client()
|
||||
# client.force_login(self.view_user)
|
||||
|
||||
# if self.url_kwargs:
|
||||
|
||||
# url = reverse(self.app_namespace + ':' + self.url_name + '-list', kwargs = self.url_kwargs)
|
||||
|
||||
# else:
|
||||
|
||||
# url = reverse(self.app_namespace + ':' + self.url_name + '-list')
|
||||
|
||||
# response = client.options( url, content_type='application/json' )
|
||||
|
||||
# assert type(response.data['urls']['return_url']) is str
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.organization_history import Organization, OrganizationHistory
|
||||
from access.models.organization_history import Tenant as Organization, OrganizationHistory
|
||||
|
||||
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
|
||||
|
||||
|
@ -1,22 +1,24 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.serializers.organization import (
|
||||
Organization,
|
||||
OrganizationModelSerializer
|
||||
Tenant,
|
||||
TenantModelSerializer
|
||||
)
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class OrganizationValidationAPI(
|
||||
TestCase,
|
||||
):
|
||||
|
||||
model = Organization
|
||||
model = Tenant
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
@ -45,7 +47,7 @@ class OrganizationValidationAPI(
|
||||
Ensure that if creating and no name is provided a validation error occurs
|
||||
"""
|
||||
|
||||
serializer = OrganizationModelSerializer(
|
||||
serializer = TenantModelSerializer(
|
||||
data = self.valid_data
|
||||
)
|
||||
|
||||
@ -65,7 +67,7 @@ class OrganizationValidationAPI(
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = OrganizationModelSerializer(
|
||||
serializer = TenantModelSerializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
@ -85,7 +87,7 @@ class OrganizationValidationAPI(
|
||||
|
||||
del data['manager']
|
||||
|
||||
serializer = OrganizationModelSerializer(
|
||||
serializer = TenantModelSerializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -17,6 +18,8 @@ from api.tests.abstract.api_permissions_viewset import APIPermissions
|
||||
from api.tests.abstract.api_serializer_viewset import SerializersTestCases
|
||||
from api.tests.abstract.test_metadata_functional import MetadataAttributesFunctional, MetaDataNavigationEntriesFunctional
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
@ -315,4 +318,4 @@ class OrganizationMetadata(
|
||||
|
||||
menu_id = 'access'
|
||||
|
||||
menu_entry_id = 'organization'
|
||||
menu_entry_id = 'tenant'
|
@ -3,7 +3,7 @@ from django.test import TestCase
|
||||
|
||||
from core.tests.abstract.model_notes_api_fields import ModelNotesNotesAPIFields
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.organization_notes import OrganizationNotes
|
||||
|
||||
|
||||
|
24
app/access/tests/functional/person/conftest.py
Normal file
24
app/access/tests/functional/person/conftest.py
Normal file
@ -0,0 +1,24 @@
|
||||
import pytest
|
||||
|
||||
from access.models.person import Person
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Person
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def create_serializer():
|
||||
|
||||
from access.serializers.entity_person import ModelSerializer
|
||||
|
||||
|
||||
yield ModelSerializer
|
@ -0,0 +1,83 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.person import Person
|
||||
from access.tests.functional.entity.test_functional_entity_metadata import (
|
||||
EntityMetadataInheritedCases
|
||||
)
|
||||
|
||||
from accounting.models.asset_base import AssetBase
|
||||
|
||||
|
||||
|
||||
class PersonMetadataTestCases(
|
||||
EntityMetadataInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Strange',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Weird',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
model = Person
|
||||
|
||||
|
||||
|
||||
|
||||
class PersonMetadataInheritedCases(
|
||||
PersonMetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {}
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
# self.url_kwargs = {
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# }
|
||||
|
||||
# self.url_view_kwargs = {
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# }
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class PersonMetadataTest(
|
||||
PersonMetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
pass
|
@ -0,0 +1,91 @@
|
||||
import pytest
|
||||
|
||||
from access.tests.functional.entity.test_functional_entity_permission import (
|
||||
EntityPermissionsAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class PersonPermissionsAPITestCases(
|
||||
EntityPermissionsAPIInheritedCases,
|
||||
):
|
||||
|
||||
add_data: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Strange',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
# app_namespace = 'v2'
|
||||
|
||||
# change_data = {}
|
||||
|
||||
# delete_data = {}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Weird',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
# url_kwargs: dict = {}
|
||||
|
||||
# url_name = '_api_v2_entity'
|
||||
|
||||
# url_view_kwargs: dict = {}
|
||||
|
||||
|
||||
|
||||
class PersonPermissionsAPIInheritedCases(
|
||||
PersonPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
# url_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
# @pytest.fixture(scope='class')
|
||||
# def inherited_var_setup(self, request):
|
||||
|
||||
# request.cls.url_kwargs.update({
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# })
|
||||
|
||||
# request.cls.url_view_kwargs.update({
|
||||
# 'entity_model': self.model._meta.sub_model_type
|
||||
# })
|
||||
|
||||
|
||||
|
||||
# @pytest.fixture(scope='class', autouse = True)
|
||||
# def class_setup(self, request, django_db_blocker,
|
||||
# model,
|
||||
# var_setup,
|
||||
# prepare,
|
||||
# inherited_var_setup,
|
||||
# diff_org_model,
|
||||
# create_model,
|
||||
# ):
|
||||
|
||||
# pass
|
||||
|
||||
|
||||
class PersonPermissionsAPIPyTest(
|
||||
PersonPermissionsAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,161 +1,88 @@
|
||||
import pytest
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.serializers.entity_person import (
|
||||
Person,
|
||||
ModelSerializer
|
||||
)
|
||||
from access.tests.functional.entity.test_functional_entity_serializer import (
|
||||
MockView,
|
||||
EntitySerializerInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SerializerTestCases(
|
||||
EntitySerializerInheritedCases,
|
||||
class PersonSerializerTestCases(
|
||||
EntitySerializerInheritedCases
|
||||
):
|
||||
|
||||
create_model_serializer = ModelSerializer
|
||||
"""Serializer to test"""
|
||||
|
||||
duplicate_f_name_l_name_dob: dict = {
|
||||
'f_name': 'fred',
|
||||
'm_name': 'D',
|
||||
'l_name': 'Flinstone',
|
||||
'dob': '2025-04-08',
|
||||
parameterized_test_data: dict = {
|
||||
"model_notes": {
|
||||
'will_create': True,
|
||||
},
|
||||
"f_name": {
|
||||
'will_create': False,
|
||||
'exception_key': 'required'
|
||||
},
|
||||
"m_name": {
|
||||
'will_create': True,
|
||||
},
|
||||
"l_name": {
|
||||
'will_create': False,
|
||||
'exception_key': 'required'
|
||||
},
|
||||
"dob": {
|
||||
'will_create': True,
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item_duplicate_f_name_l_name_dob: dict = {
|
||||
'f_name': 'fred',
|
||||
'm_name': 'D',
|
||||
'l_name': 'Flinstone',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
valid_data: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
model = Person
|
||||
"""Model to test"""
|
||||
|
||||
valid_data: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Strange',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_no_f_name_exception(self):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and field f_name is missing
|
||||
a validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['f_name']
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
serializer.is_valid(raise_exception = True)
|
||||
|
||||
assert err.value.get_codes()['f_name'][0] == 'required'
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_no_m_name(self):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and field f_name is missing
|
||||
no validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['m_name']
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
assert serializer.is_valid(raise_exception = True)
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_no_l_name_exception(self):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and field l_name is missing
|
||||
a validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['l_name']
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
serializer.is_valid(raise_exception = True)
|
||||
|
||||
assert err.value.get_codes()['l_name'][0] == 'required'
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_no_dob(self):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and field dob is missing
|
||||
no validation error occurs.
|
||||
"""
|
||||
|
||||
data = self.valid_data.copy()
|
||||
|
||||
del data['dob']
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
)
|
||||
|
||||
assert serializer.is_valid(raise_exception = True)
|
||||
|
||||
|
||||
|
||||
def test_serializer_validation_duplicate_f_name_l_name_dob(self):
|
||||
def test_serializer_validation_duplicate_f_name_l_name_dob(self, model, create_serializer):
|
||||
"""Serializer Validation Check
|
||||
|
||||
Ensure that when creating with valid data and fields f_name, l_name and
|
||||
dob already exists in the db a validation error occurs.
|
||||
"""
|
||||
|
||||
self.model.objects.create(
|
||||
organization = self.organization,
|
||||
**self.kwargs_create_item_duplicate_f_name_l_name_dob
|
||||
valid_data = self.valid_data.copy()
|
||||
|
||||
valid_data['f_name'] = 'duplicate'
|
||||
|
||||
valid_data['organization'] = self.organization
|
||||
|
||||
obj = model.objects.create(
|
||||
**valid_data
|
||||
)
|
||||
|
||||
data = self.duplicate_f_name_l_name_dob.copy()
|
||||
valid_data['organization'] = self.organization.id
|
||||
|
||||
if 'email' in valid_data: # Contact Entity
|
||||
|
||||
valid_data['email'] = 'abc@xyz.qwe'
|
||||
|
||||
if 'name' in valid_data: # Company Entity
|
||||
|
||||
valid_data['name'] = 'diff'
|
||||
|
||||
if 'employee_number' in valid_data: # Employee Entity
|
||||
|
||||
valid_data['employee_number'] = 13579
|
||||
|
||||
view_set = MockView()
|
||||
|
||||
with pytest.raises(ValidationError) as err:
|
||||
|
||||
serializer = self.create_model_serializer(
|
||||
data = data
|
||||
serializer = create_serializer(
|
||||
context = {
|
||||
'view': view_set,
|
||||
},
|
||||
data = valid_data
|
||||
)
|
||||
|
||||
serializer.is_valid(raise_exception = True)
|
||||
@ -167,64 +94,18 @@ class SerializerTestCases(
|
||||
|
||||
|
||||
class PersonSerializerInheritedCases(
|
||||
SerializerTestCases,
|
||||
PersonSerializerTestCases,
|
||||
):
|
||||
|
||||
create_model_serializer = None
|
||||
"""Serializer to test"""
|
||||
|
||||
duplicate_f_name_l_name_dob: dict = None
|
||||
""" Duplicate model serializer dict
|
||||
|
||||
used for testing for duplicate f_name, l_name and dob fields.
|
||||
"""
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
""" Model kwargs to create item"""
|
||||
|
||||
kwargs_create_item_duplicate_f_name_l_name_dob: dict = None
|
||||
"""model kwargs to create object
|
||||
|
||||
**None:** Ensure that the fields of sub-model to person do not match
|
||||
`self.duplicate_f_name_l_name_dob`. if they do the wrong exception will be thrown.
|
||||
|
||||
used for testing for duplicate f_name, l_name and dob fields.
|
||||
"""
|
||||
|
||||
model = None
|
||||
"""Model to test"""
|
||||
parameterized_test_data: dict = None
|
||||
|
||||
valid_data: dict = None
|
||||
"""Valid data used by serializer to create object"""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test"""
|
||||
|
||||
self.duplicate_f_name_l_name_dob.update(
|
||||
super().duplicate_f_name_l_name_dob
|
||||
)
|
||||
|
||||
self.kwargs_create_item_duplicate_f_name_l_name_dob.update(
|
||||
super().kwargs_create_item_duplicate_f_name_l_name_dob
|
||||
)
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.valid_data.update(
|
||||
super().valid_data
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class PersonSerializerTest(
|
||||
SerializerTestCases,
|
||||
TestCase,
|
||||
class PersonSerializerPyTest(
|
||||
PersonSerializerTestCases,
|
||||
):
|
||||
|
||||
pass
|
||||
parameterized_test_data: dict = None
|
||||
|
@ -2,101 +2,38 @@ from django.test import TestCase
|
||||
|
||||
from access.models.person import Person
|
||||
from access.tests.functional.entity.test_functional_entity_viewset import (
|
||||
EntityMetadataInheritedCases,
|
||||
EntityPermissionsAPIInheritedCases,
|
||||
EntityViewSetInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
class ViewSetTestCases(
|
||||
EntityViewSetInheritedCases,
|
||||
):
|
||||
|
||||
add_data = {
|
||||
add_data: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Strange',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item = {
|
||||
kwargs_create_item: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Weird',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
kwargs_create_item_diff_org: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
model = Person
|
||||
|
||||
url_kwargs: dict = {}
|
||||
|
||||
url_view_kwargs: dict = {}
|
||||
|
||||
|
||||
|
||||
class PermissionsAPITestCases(
|
||||
ViewSetBase,
|
||||
EntityPermissionsAPIInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class PersonPermissionsAPIInheritedCases(
|
||||
PermissionsAPITestCases,
|
||||
):
|
||||
|
||||
add_data: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.add_data.update(
|
||||
super().add_data
|
||||
)
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class PersonPermissionsAPITest(
|
||||
PermissionsAPITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ViewSetTestCases(
|
||||
ViewSetBase,
|
||||
EntityViewSetInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class PersonViewSetInheritedCases(
|
||||
@ -105,21 +42,19 @@ class PersonViewSetInheritedCases(
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
self.kwargs_create_item = {
|
||||
**super().kwargs_create_item,
|
||||
**self.kwargs_create_item
|
||||
}
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
self.kwargs_create_item_diff_org = {
|
||||
**super().kwargs_create_item_diff_org,
|
||||
**self.kwargs_create_item_diff_org
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
@ -129,50 +64,4 @@ class PersonViewSetTest(
|
||||
ViewSetTestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class MetadataTestCases(
|
||||
ViewSetBase,
|
||||
EntityMetadataInheritedCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class PersonMetadataInheritedCases(
|
||||
MetadataTestCases,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
kwargs_create_item_diff_org: dict = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_create_item.update(
|
||||
super().kwargs_create_item
|
||||
)
|
||||
|
||||
self.kwargs_create_item_diff_org.update(
|
||||
super().kwargs_create_item_diff_org
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class PersonMetadataTest(
|
||||
MetadataTestCases,
|
||||
TestCase,
|
||||
|
||||
):
|
||||
|
||||
pass
|
||||
|
@ -5,7 +5,7 @@ from django.test import TestCase
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.serializers.role import Role, ModelSerializer
|
||||
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
from django.contrib.auth.models import Permission, User
|
||||
import django
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from access.models.role import Role
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -15,6 +16,8 @@ from api.tests.abstract.api_serializer_viewset import SerializersTestCases
|
||||
|
||||
from settings.models.app_settings import AppSettings
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
|
@ -1,16 +1,17 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -19,6 +20,8 @@ from api.tests.abstract.test_metadata_functional import MetadataAttributesFuncti
|
||||
from api.tests.abstract.api_permissions_viewset import APIPermissions
|
||||
from api.tests.abstract.api_serializer_viewset import SerializersTestCases
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
|
@ -1,6 +1,7 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
@ -8,7 +9,7 @@ from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.middleware.request import Tenancy
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
|
||||
from access.serializers.teams import (
|
||||
Team,
|
||||
@ -17,6 +18,8 @@ from access.serializers.teams import (
|
||||
|
||||
from settings.models.app_settings import AppSettings
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class MockView:
|
||||
|
@ -1,16 +1,17 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -18,6 +19,8 @@ from api.tests.abstract.test_metadata_functional import MetadataAttributesFuncti
|
||||
from api.tests.abstract.api_permissions_viewset import APIPermissions
|
||||
from api.tests.abstract.api_serializer_viewset import SerializersTestCases
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class ViewSetBase:
|
||||
|
@ -1,12 +1,13 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
from access.serializers.team_user import (
|
||||
@ -14,6 +15,8 @@ from access.serializers.team_user import (
|
||||
TeamUserModelSerializer
|
||||
)
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class MockView:
|
||||
|
14
app/access/tests/unit/company/conftest.py
Normal file
14
app/access/tests/unit/company/conftest.py
Normal file
@ -0,0 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from access.models.company_base import Company
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Company
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
@ -0,0 +1,37 @@
|
||||
from access.tests.unit.entity.test_unit_entity_api_fields import (
|
||||
EntityAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CompanyAPITestCases(
|
||||
EntityAPIInheritedCases,
|
||||
):
|
||||
|
||||
parameterized_test_data = {
|
||||
'name': {
|
||||
'expected': str
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'name': 'Ian'
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CompanyAPIInheritedCases(
|
||||
CompanyAPITestCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
|
||||
class CompanyAPIPyTest(
|
||||
CompanyAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
105
app/access/tests/unit/company/test_unit_company_model.py
Normal file
105
app/access/tests/unit/company/test_unit_company_model.py
Normal file
@ -0,0 +1,105 @@
|
||||
import pytest
|
||||
|
||||
from django.db import models
|
||||
|
||||
from access.models.company_base import Company
|
||||
|
||||
from access.tests.unit.entity.test_unit_entity_model import (
|
||||
EntityModelInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CompanyModelTestCases(
|
||||
EntityModelInheritedCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'name': 'Ian',
|
||||
}
|
||||
|
||||
sub_model_type = 'company'
|
||||
"""Sub Model Type
|
||||
|
||||
sub-models must have this attribute defined in `ModelName.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
parameterized_fields: dict = {
|
||||
"name": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
def test_class_inherits_company(self):
|
||||
""" Class inheritence
|
||||
|
||||
TenancyObject must inherit SaveHistory
|
||||
"""
|
||||
|
||||
assert issubclass(self.model, Company)
|
||||
|
||||
|
||||
def test_attribute_value_history_app_label(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_app_label has been set, override this test case with the value
|
||||
of attribute `history_app_label`
|
||||
"""
|
||||
|
||||
assert self.model.history_app_label == 'access'
|
||||
|
||||
|
||||
def test_attribute_value_history_model_name(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_model_name has been set, override this test case with the value
|
||||
of attribute `history_model_name`
|
||||
"""
|
||||
|
||||
assert self.model.history_model_name == 'company'
|
||||
|
||||
|
||||
|
||||
def test_function_value_get_url(self):
|
||||
|
||||
assert self.item.get_url() == '/api/v2/access/entity/company/' + str(self.item.id)
|
||||
|
||||
|
||||
|
||||
class CompanyModelInheritedCases(
|
||||
CompanyModelTestCases,
|
||||
):
|
||||
"""Sub-Ticket Test Cases
|
||||
|
||||
Test Cases for Ticket models that inherit from model Entity
|
||||
"""
|
||||
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
model = None
|
||||
|
||||
sub_model_type = None
|
||||
"""Ticket Sub Model Type
|
||||
|
||||
Ticket sub-models must have this attribute defined in `ModelNam.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class CompanyModelPyTest(
|
||||
CompanyModelTestCases,
|
||||
):
|
||||
|
||||
|
||||
def test_function_value_get_related_model(self):
|
||||
"""Function test
|
||||
|
||||
Confirm function `get_related_model` is None for base model
|
||||
"""
|
||||
|
||||
assert self.item.get_related_model() is None
|
36
app/access/tests/unit/company/test_unit_company_viewset.py
Normal file
36
app/access/tests/unit/company/test_unit_company_viewset.py
Normal file
@ -0,0 +1,36 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.company_base import Company
|
||||
from access.tests.unit.entity.test_unit_entity_viewset import (
|
||||
EntityViewsetInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ViewsetTestCases(
|
||||
EntityViewsetInheritedCases,
|
||||
):
|
||||
|
||||
model: str = Company
|
||||
|
||||
|
||||
|
||||
class CompanyViewsetInheritedCases(
|
||||
ViewsetTestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Company
|
||||
"""
|
||||
|
||||
model: str = None
|
||||
"""name of the model to test"""
|
||||
|
||||
|
||||
|
||||
class CompanyViewsetTest(
|
||||
ViewsetTestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
14
app/access/tests/unit/contact/conftest.py
Normal file
14
app/access/tests/unit/contact/conftest.py
Normal file
@ -0,0 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from access.models.contact import Contact
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Contact
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
@ -0,0 +1,40 @@
|
||||
from access.tests.unit.person.test_unit_person_api_fields import (
|
||||
PersonAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ContactAPITestCases(
|
||||
PersonAPIInheritedCases,
|
||||
):
|
||||
|
||||
parameterized_test_data = {
|
||||
'email': {
|
||||
'expected': str
|
||||
},
|
||||
'directory': {
|
||||
'expected': bool
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ContactAPIInheritedCases(
|
||||
ContactAPITestCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
|
||||
class ContactAPIPyTest(
|
||||
ContactAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,90 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.contact import Contact
|
||||
|
||||
from access.tests.unit.person.test_unit_person_api_v2 import (
|
||||
PersonAPIInheritedCases,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class APITestCases(
|
||||
PersonAPIInheritedCases,
|
||||
):
|
||||
|
||||
model = Contact
|
||||
|
||||
kwargs_item_create: dict = {
|
||||
'email': 'ipfunny@unit.test',
|
||||
}
|
||||
|
||||
url_ns_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
def test_api_field_exists_email(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
email field must exist
|
||||
"""
|
||||
|
||||
assert 'email' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_email(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
email field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['email']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_directory(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
directory field must exist
|
||||
"""
|
||||
|
||||
assert 'directory' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_directory(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
directory field must be bool
|
||||
"""
|
||||
|
||||
assert type(self.api_data['directory']) is bool
|
||||
|
||||
|
||||
|
||||
class ContactAPIInheritedCases(
|
||||
APITestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Contact
|
||||
"""
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create.update(
|
||||
super().kwargs_item_create
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
class ContactAPITest(
|
||||
APITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
@ -1,100 +1,110 @@
|
||||
from django.db.models.fields import NOT_PROVIDED
|
||||
from django.test import TestCase
|
||||
import pytest
|
||||
|
||||
from django.db import models
|
||||
|
||||
from access.models.contact import Contact
|
||||
from access.tests.unit.person.test_unit_person_model import (
|
||||
Person,
|
||||
PersonModelInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ModelTestCases(
|
||||
class ContactModelTestCases(
|
||||
PersonModelInheritedCases,
|
||||
):
|
||||
|
||||
model = Contact
|
||||
|
||||
kwargs_item_create: dict = {
|
||||
kwargs_create_item: dict = {
|
||||
'email': 'ipweird@unit.test',
|
||||
}
|
||||
|
||||
sub_model_type = 'contact'
|
||||
"""Sub Model Type
|
||||
|
||||
sub-models must have this attribute defined in `ModelName.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
parameterized_fields: dict = {
|
||||
"email": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
},
|
||||
"directory": {
|
||||
'field_type': models.fields.BooleanField,
|
||||
'field_parameter_default_exists': True,
|
||||
'field_parameter_default_value': True,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
def test_model_field_directory_optional(self):
|
||||
"""Test Field
|
||||
def test_class_inherits_contact(self):
|
||||
""" Class inheritence
|
||||
|
||||
Field `dob` must be an optional field
|
||||
TenancyObject must inherit SaveHistory
|
||||
"""
|
||||
|
||||
assert self.model._meta.get_field('directory').blank
|
||||
assert issubclass(self.model, Contact)
|
||||
|
||||
|
||||
def test_model_field_directory_optional_default(self):
|
||||
"""Test Field
|
||||
# def test_attribute_value_history_app_label(self):
|
||||
# """Attribute Type
|
||||
|
||||
Field `directory` default value is `True`
|
||||
# history_app_label has been set, override this test case with the value
|
||||
# of attribute `history_app_label`
|
||||
# """
|
||||
|
||||
# assert self.model.history_app_label == 'access'
|
||||
|
||||
|
||||
def test_attribute_value_history_model_name(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_model_name has been set, override this test case with the value
|
||||
of attribute `history_model_name`
|
||||
"""
|
||||
|
||||
assert (
|
||||
self.model._meta.get_field('directory').default is True
|
||||
and self.model._meta.get_field('directory').null is False
|
||||
)
|
||||
assert self.model.history_model_name == 'contact'
|
||||
|
||||
|
||||
def test_model_field_email_mandatory(self):
|
||||
"""Test Field
|
||||
|
||||
Field `email` must be a mandatory field
|
||||
"""
|
||||
|
||||
assert(
|
||||
not (
|
||||
self.model._meta.get_field('email').blank
|
||||
and self.model._meta.get_field('email').null
|
||||
)
|
||||
and self.model._meta.get_field('email').default is NOT_PROVIDED
|
||||
)
|
||||
|
||||
|
||||
def test_model_inherits_person(self):
|
||||
"""Test model inheritence
|
||||
|
||||
model must inherit from Entity sub-model `Person`
|
||||
"""
|
||||
|
||||
assert issubclass(self.model, Person)
|
||||
def test_function_value_get_url(self):
|
||||
|
||||
assert self.item.get_url() == '/api/v2/access/entity/contact/' + str(self.item.id)
|
||||
|
||||
|
||||
|
||||
class ContactModelInheritedCases(
|
||||
ModelTestCases,
|
||||
ContactModelTestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
"""Sub-Ticket Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Contact
|
||||
Test Cases for Ticket models that inherit from model Entity
|
||||
"""
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create.update(
|
||||
super().kwargs_item_create
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
sub_model_type = None
|
||||
"""Ticket Sub Model Type
|
||||
|
||||
Ticket sub-models must have this attribute defined in `ModelNam.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class ContactModelTest(
|
||||
ModelTestCases,
|
||||
TestCase,
|
||||
class ContactModelPyTest(
|
||||
ContactModelTestCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
def test_function_value_get_related_model(self):
|
||||
"""Function test
|
||||
|
||||
Confirm function `get_related_model` is None for base model
|
||||
"""
|
||||
|
||||
assert self.item.get_related_model() is None
|
||||
|
14
app/access/tests/unit/entity/conftest.py
Normal file
14
app/access/tests/unit/entity/conftest.py
Normal file
@ -0,0 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from access.models.entity import Entity
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Entity
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
78
app/access/tests/unit/entity/test_unit_entity_api_fields.py
Normal file
78
app/access/tests/unit/entity/test_unit_entity_api_fields.py
Normal file
@ -0,0 +1,78 @@
|
||||
import pytest
|
||||
|
||||
from access.models.entity import Entity
|
||||
|
||||
from api.tests.unit.test_unit_api_fields import (
|
||||
APIFieldsInheritedCases,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class EntityAPITestCases(
|
||||
APIFieldsInheritedCases,
|
||||
):
|
||||
|
||||
base_model = Entity
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def setup_model(self, request,
|
||||
model,
|
||||
):
|
||||
|
||||
if model != self.base_model:
|
||||
|
||||
request.cls.url_view_kwargs.update({
|
||||
'entity_model': model._meta.sub_model_type,
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class', autouse = True)
|
||||
def class_setup(self,
|
||||
setup_pre,
|
||||
setup_model,
|
||||
create_model,
|
||||
setup_post,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
parameterized_test_data = {
|
||||
'entity_type': {
|
||||
'expected': str
|
||||
},
|
||||
'_urls.history': {
|
||||
'expected': str
|
||||
},
|
||||
'_urls.knowledge_base': {
|
||||
'expected': str
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'entity_type': 'entity',
|
||||
}
|
||||
|
||||
url_ns_name = '_api_v2_entity'
|
||||
"""Url namespace (optional, if not required) and url name"""
|
||||
|
||||
|
||||
|
||||
class EntityAPIInheritedCases(
|
||||
EntityAPITestCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
url_ns_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
|
||||
class EntityAPIPyTest(
|
||||
EntityAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,215 +0,0 @@
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
# from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.entity import Entity
|
||||
from access.models.organization import Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_fields import APITenancyObject
|
||||
|
||||
|
||||
|
||||
class APITestCases(
|
||||
APITenancyObject,
|
||||
):
|
||||
|
||||
model = None
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
|
||||
url_ns_name = None
|
||||
"""Url namespace (optional, if not required) and url name"""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
"""Setup Test
|
||||
|
||||
1. Create an organization for user and item
|
||||
2. Create an item
|
||||
|
||||
"""
|
||||
|
||||
self.organization = Organization.objects.create(name='test_org')
|
||||
|
||||
|
||||
self.item = self.model.objects.create(
|
||||
organization = self.organization,
|
||||
model_notes = 'random notes',
|
||||
**self.kwargs_item_create
|
||||
)
|
||||
|
||||
|
||||
self.url_view_kwargs = {
|
||||
'pk': self.item.id
|
||||
}
|
||||
|
||||
if self.model._meta.model_name != 'entity':
|
||||
|
||||
self.url_view_kwargs.update({
|
||||
'entity_model': self.item.entity_type,
|
||||
})
|
||||
|
||||
view_permissions = Permission.objects.get(
|
||||
codename = 'view_' + self.model._meta.model_name,
|
||||
content_type = ContentType.objects.get(
|
||||
app_label = self.model._meta.app_label,
|
||||
model = self.model._meta.model_name,
|
||||
)
|
||||
)
|
||||
|
||||
view_team = Team.objects.create(
|
||||
team_name = 'view_team',
|
||||
organization = self.organization,
|
||||
)
|
||||
|
||||
view_team.permissions.set([view_permissions])
|
||||
|
||||
self.view_user = User.objects.create_user(username="test_user_view", password="password")
|
||||
TeamUsers.objects.create(
|
||||
team = view_team,
|
||||
user = self.view_user
|
||||
)
|
||||
|
||||
client = Client()
|
||||
url = reverse('v2:' + self.url_ns_name + '-detail', kwargs=self.url_view_kwargs)
|
||||
|
||||
|
||||
client.force_login(self.view_user)
|
||||
response = client.get(url)
|
||||
|
||||
self.api_data = response.data
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_entity_type(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
entity_type field must exist
|
||||
"""
|
||||
|
||||
assert 'entity_type' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_entity_type(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
entity_type field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['entity_type']) is str
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_url_history(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
_urls.history field must exist
|
||||
"""
|
||||
|
||||
assert 'history' in self.api_data['_urls']
|
||||
|
||||
|
||||
def test_api_field_type_url_history(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
_urls.history field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['_urls']['history']) is str
|
||||
|
||||
|
||||
def test_api_field_type_url_history_value(self):
|
||||
""" Test for url value
|
||||
|
||||
_urls.history field must use the endpoint for entity model
|
||||
"""
|
||||
|
||||
assert str(self.api_data['_urls']['history']).endswith('/' + str(self.item._meta.app_label) + '/' + str(self.item._meta.model_name) + '/' + str(self.item.pk) + '/history')
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_url_knowledge_base(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
_urls.knowledge_base field must exist
|
||||
"""
|
||||
|
||||
assert 'knowledge_base' in self.api_data['_urls']
|
||||
|
||||
|
||||
def test_api_field_type_url_knowledge_base(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
_urls.knowledge_base field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['_urls']['knowledge_base']) is str
|
||||
|
||||
|
||||
def test_api_field_type_url_knowledge_base_value(self):
|
||||
""" Test for url value
|
||||
|
||||
_urls.knowledge_base field must use the endpoint for entity model
|
||||
"""
|
||||
|
||||
assert str(self.api_data['_urls']['knowledge_base']).endswith('/assistance/entity/' + str(self.item.pk) + '/knowledge_base')
|
||||
|
||||
|
||||
|
||||
class EntityAPIInheritedCases(
|
||||
APITestCases,
|
||||
):
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
url_ns_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create.update({
|
||||
'entity_type': self.model._meta.model_name
|
||||
})
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
def test_api_field_exists_entity_value(self):
|
||||
""" Test for value of API Field
|
||||
|
||||
entity_type field must match model name
|
||||
"""
|
||||
|
||||
assert self.api_data['entity_type'] == self.model._meta.model_name
|
||||
|
||||
|
||||
|
||||
class EntityAPITest(
|
||||
APITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
|
||||
model = Entity
|
||||
|
||||
url_ns_name = '_api_v2_entity'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create = {
|
||||
'entity_type': 'entity'
|
||||
}
|
||||
|
||||
super().setUpTestData()
|
@ -1,27 +1,117 @@
|
||||
from django.test import TestCase
|
||||
import pytest
|
||||
|
||||
from django.db import models
|
||||
|
||||
from access.models.entity import Entity
|
||||
|
||||
from app.tests.unit.test_unit_models import (
|
||||
TenancyObjectInheritedCases
|
||||
PyTestTenancyObjectInheritedCases,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
class EntityModelTestCases(
|
||||
TenancyObjectInheritedCases,
|
||||
PyTestTenancyObjectInheritedCases,
|
||||
):
|
||||
|
||||
model = Entity
|
||||
base_model = Entity
|
||||
|
||||
kwargs_item_create: dict = {}
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
sub_model_type = 'entity'
|
||||
"""Sub Model Type
|
||||
|
||||
sub-models must have this attribute defined in `ModelName.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
parameterized_fields: dict = {
|
||||
"entity_type": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
# 'field_parameter_default_value': 'entity',
|
||||
'field_parameter_verbose_name_type': str
|
||||
},
|
||||
# "asset_number": {
|
||||
# 'field_type': models.fields.CharField,
|
||||
# 'field_parameter_default_exists': False,
|
||||
# 'field_parameter_verbose_name_type': str,
|
||||
# },
|
||||
# "serial_number": {
|
||||
# 'field_type': models.fields.CharField,
|
||||
# 'field_parameter_default_exists': False,
|
||||
# 'field_parameter_verbose_name_type': str,
|
||||
# }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def setup_model(self,
|
||||
request,
|
||||
model,
|
||||
django_db_blocker,
|
||||
organization_one,
|
||||
organization_two
|
||||
):
|
||||
|
||||
with django_db_blocker.unblock():
|
||||
|
||||
request.cls.organization = organization_one
|
||||
|
||||
request.cls.different_organization = organization_two
|
||||
|
||||
kwargs_create_item = {}
|
||||
|
||||
for base in reversed(request.cls.__mro__):
|
||||
|
||||
if hasattr(base, 'kwargs_create_item'):
|
||||
|
||||
if base.kwargs_create_item is None:
|
||||
|
||||
continue
|
||||
|
||||
kwargs_create_item.update(**base.kwargs_create_item)
|
||||
|
||||
|
||||
if len(kwargs_create_item) > 0:
|
||||
|
||||
request.cls.kwargs_create_item = kwargs_create_item
|
||||
|
||||
|
||||
if 'organization' not in request.cls.kwargs_create_item:
|
||||
|
||||
request.cls.kwargs_create_item.update({
|
||||
'organization': request.cls.organization
|
||||
})
|
||||
|
||||
yield
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class', autouse = True)
|
||||
def class_setup(self,
|
||||
setup_model,
|
||||
create_model,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def test_class_inherits_entity(self):
|
||||
""" Class inheritence
|
||||
|
||||
TenancyObject must inherit SaveHistory
|
||||
"""
|
||||
|
||||
assert issubclass(self.model, Entity)
|
||||
|
||||
|
||||
def test_attribute_type_history_app_label(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_app_name is of type str
|
||||
history_app_label is of type str
|
||||
"""
|
||||
|
||||
assert type(self.model.history_app_label) is str
|
||||
@ -30,11 +120,11 @@ class EntityModelTestCases(
|
||||
def test_attribute_value_history_app_label(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_app_name is of type str
|
||||
history_app_label has been set, override this test case with the value
|
||||
of attribute `history_app_label`
|
||||
"""
|
||||
|
||||
assert self.model.history_app_label == self.model._meta.app_label
|
||||
|
||||
assert self.model.history_app_label == 'access'
|
||||
|
||||
|
||||
|
||||
@ -50,10 +140,11 @@ class EntityModelTestCases(
|
||||
def test_attribute_value_history_model_name(self):
|
||||
"""Attribute Type
|
||||
|
||||
history_model_name is of type str
|
||||
history_model_name has been set, override this test case with the value
|
||||
of attribute `history_model_name`
|
||||
"""
|
||||
|
||||
assert self.model.history_model_name == self.model._meta.model_name
|
||||
assert self.model.history_model_name == 'entity'
|
||||
|
||||
|
||||
|
||||
@ -69,7 +160,8 @@ class EntityModelTestCases(
|
||||
def test_attribute_value_kb_model_name(self):
|
||||
"""Attribute Type
|
||||
|
||||
kb_model_name is of type str
|
||||
kb_model_name has been set, override this test case with the value
|
||||
of attribute `kb_model_name`
|
||||
"""
|
||||
|
||||
assert self.model.kb_model_name == 'entity'
|
||||
@ -88,40 +180,95 @@ class EntityModelTestCases(
|
||||
def test_attribute_value_note_basename(self):
|
||||
"""Attribute Type
|
||||
|
||||
note_basename is of type str
|
||||
note_basename has been set, override this test case with the value
|
||||
of attribute `note_basename`
|
||||
"""
|
||||
|
||||
assert self.model.note_basename == '_api_v2_entity_note'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# def test_function_is_property_get_model_type(self):
|
||||
# """Function test
|
||||
|
||||
# Confirm function `get_model_type` is a property
|
||||
# """
|
||||
|
||||
# assert type(self.model.get_model_type) is property
|
||||
|
||||
|
||||
# def test_function_value_get_model_type(self):
|
||||
# """Function test
|
||||
|
||||
# Confirm function `get_model_type` does not have a value of None
|
||||
# value should be equaul to Meta.sub_model_type
|
||||
# """
|
||||
|
||||
# assert self.item.get_model_type == self.item._meta.sub_model_type
|
||||
|
||||
|
||||
|
||||
|
||||
def test_function_value_get_related_model(self):
|
||||
"""Function test
|
||||
|
||||
Confirm function `get_related_model` is of the sub-model type
|
||||
"""
|
||||
|
||||
assert type(self.item.get_related_model()) == self.model
|
||||
|
||||
|
||||
def test_function_value_get_url(self):
|
||||
|
||||
assert self.item.get_url() == '/api/v2/access/entity/' + str(self.item.id)
|
||||
|
||||
|
||||
|
||||
class EntityModelInheritedCases(
|
||||
EntityModelTestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
"""Sub-Ticket Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Entity
|
||||
Test Cases for Ticket models that inherit from model Entity
|
||||
"""
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
sub_model_type = None
|
||||
"""Ticket Sub Model Type
|
||||
|
||||
Ticket sub-models must have this attribute defined in `ModelNam.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
self.kwargs_item_create.update(
|
||||
super().kwargs_item_create
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
# def test_function_value_get_model_type(self):
|
||||
# """Function test
|
||||
|
||||
# Confirm function `get_model_type` does not have a value of None
|
||||
# value should be equaul to Meta.sub_model_type
|
||||
# """
|
||||
|
||||
# assert self.item.get_model_type == self.item._meta.sub_model_type
|
||||
|
||||
|
||||
|
||||
class EntityModelTest(
|
||||
class EntityModelPyTest(
|
||||
EntityModelTestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
def test_function_value_get_related_model(self):
|
||||
"""Function test
|
||||
|
||||
Confirm function `get_related_model` is None for base model
|
||||
"""
|
||||
|
||||
assert self.item.get_related_model() is None
|
||||
|
@ -1,7 +1,9 @@
|
||||
import django
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from django.contrib.auth.models import User, Permission, AnonymousUser
|
||||
from django.contrib.auth.models import Permission, AnonymousUser
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
@ -13,7 +15,7 @@ from api.viewsets.common import ModelViewSet
|
||||
|
||||
from access.mixins.organization import OrganizationMixin
|
||||
from access.mixins.permissions import OrganizationPermissionMixin
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -23,6 +25,8 @@ from core.models.manufacturer import Manufacturer
|
||||
|
||||
from settings.models.app_settings import AppSettings
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class MyMockView(
|
||||
|
@ -1,18 +1,21 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,21 +1,24 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
|
||||
from api.tests.abstract.api_fields import APICommonFields
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
class OrganizationAPI(
|
||||
TestCase,
|
||||
|
@ -1,6 +1,7 @@
|
||||
# from django.conf import settings
|
||||
import django
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase, Client
|
||||
@ -9,15 +10,17 @@ import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
from access.tests.abstract.model_permissions_organization_manager import OrganizationManagerModelPermissionChange, OrganizationManagerModelPermissionView
|
||||
|
||||
from app.tests.abstract.model_permissions import ModelPermissionsView, ModelPermissionsChange
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
class OrganizationPermissions(
|
||||
|
||||
class TenantPermissions(
|
||||
TestCase,
|
||||
ModelPermissionsView,
|
||||
ModelPermissionsChange,
|
||||
@ -25,7 +28,7 @@ class OrganizationPermissions(
|
||||
OrganizationManagerModelPermissionView,
|
||||
):
|
||||
|
||||
model = Organization
|
||||
model = Tenant
|
||||
|
||||
app_namespace = 'Access'
|
||||
|
||||
@ -50,11 +53,11 @@ class OrganizationPermissions(
|
||||
4. create a user per team
|
||||
"""
|
||||
|
||||
organization = Organization.objects.create(name='test_org')
|
||||
organization = Tenant.objects.create(name='test_org')
|
||||
|
||||
self.organization = organization
|
||||
|
||||
different_organization = Organization.objects.create(
|
||||
different_organization = Tenant.objects.create(
|
||||
name='test_different_organization'
|
||||
)
|
||||
|
||||
|
@ -1,18 +1,21 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_permissions import APIPermissionChange, APIPermissionView
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class OrganizationPermissionsAPI(TestCase, APIPermissionChange, APIPermissionView):
|
||||
|
@ -7,7 +7,7 @@ import unittest
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@ from django.test import TestCase
|
||||
|
||||
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
|
||||
|
||||
from access.models.organization_history import Organization, OrganizationHistory
|
||||
from access.models.organization_history import Tenant as Organization, OrganizationHistory
|
||||
|
||||
|
||||
|
||||
|
14
app/access/tests/unit/person/conftest.py
Normal file
14
app/access/tests/unit/person/conftest.py
Normal file
@ -0,0 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from access.models.person import Person
|
||||
|
||||
|
||||
|
||||
@pytest.fixture( scope = 'class')
|
||||
def model(request):
|
||||
|
||||
request.cls.model = Person
|
||||
|
||||
yield request.cls.model
|
||||
|
||||
del request.cls.model
|
50
app/access/tests/unit/person/test_unit_person_api_fields.py
Normal file
50
app/access/tests/unit/person/test_unit_person_api_fields.py
Normal file
@ -0,0 +1,50 @@
|
||||
from access.tests.unit.entity.test_unit_entity_api_fields import (
|
||||
EntityAPIInheritedCases
|
||||
)
|
||||
|
||||
|
||||
|
||||
class PersonAPITestCases(
|
||||
EntityAPIInheritedCases,
|
||||
):
|
||||
|
||||
parameterized_test_data = {
|
||||
'f_name': {
|
||||
'expected': str
|
||||
},
|
||||
'm_name': {
|
||||
'expected': str
|
||||
},
|
||||
'l_name': {
|
||||
'expected': str
|
||||
},
|
||||
'dob': {
|
||||
'expected': str
|
||||
}
|
||||
}
|
||||
|
||||
kwargs_create_item: dict = {
|
||||
'entity_type': 'person',
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class PersonAPIInheritedCases(
|
||||
PersonAPITestCases,
|
||||
):
|
||||
|
||||
kwargs_create_item: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
|
||||
class PersonAPIPyTest(
|
||||
PersonAPITestCases,
|
||||
):
|
||||
|
||||
pass
|
@ -1,127 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.person import Person
|
||||
|
||||
from access.tests.unit.entity.test_unit_entity_api_v2 import (
|
||||
EntityAPIInheritedCases,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class APITestCases(
|
||||
EntityAPIInheritedCases,
|
||||
):
|
||||
|
||||
model = Person
|
||||
|
||||
kwargs_item_create: dict = {}
|
||||
|
||||
url_ns_name = '_api_v2_entity_sub'
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create.update({
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
})
|
||||
|
||||
super().setUpTestData()
|
||||
|
||||
|
||||
|
||||
def test_api_field_exists_f_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
f_name field must exist
|
||||
"""
|
||||
|
||||
assert 'f_name' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_f_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
f_name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['f_name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_m_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
m_name field must exist
|
||||
"""
|
||||
|
||||
assert 'm_name' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_f_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
m_name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['m_name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_l_name(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
l_name field must exist
|
||||
"""
|
||||
|
||||
assert 'l_name' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_f_name(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
l_name field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['l_name']) is str
|
||||
|
||||
|
||||
def test_api_field_exists_dob(self):
|
||||
""" Test for existance of API Field
|
||||
|
||||
dob field must exist
|
||||
"""
|
||||
|
||||
assert 'dob' in self.api_data
|
||||
|
||||
|
||||
def test_api_field_type_dob(self):
|
||||
""" Test for type for API Field
|
||||
|
||||
dob field must be str
|
||||
"""
|
||||
|
||||
assert type(self.api_data['dob']) is str
|
||||
|
||||
|
||||
|
||||
class PersonAPIInheritedCases(
|
||||
APITestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Person
|
||||
"""
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
class PersonAPITest(
|
||||
APITestCases,
|
||||
TestCase,
|
||||
):
|
||||
|
||||
pass
|
@ -1,5 +1,6 @@
|
||||
from django.db.models.fields import NOT_PROVIDED
|
||||
from django.test import TestCase
|
||||
import pytest
|
||||
|
||||
from django.db import models
|
||||
|
||||
from access.models.person import Person
|
||||
from access.tests.unit.entity.test_unit_entity_model import (
|
||||
@ -8,88 +9,114 @@ from access.tests.unit.entity.test_unit_entity_model import (
|
||||
|
||||
|
||||
|
||||
class ModelTestCases(
|
||||
class PersonModelTestCases(
|
||||
EntityModelInheritedCases,
|
||||
):
|
||||
|
||||
model = Person
|
||||
|
||||
kwargs_item_create: dict = {
|
||||
kwargs_create_item: dict = {
|
||||
'f_name': 'Ian',
|
||||
'm_name': 'Peter',
|
||||
'l_name': 'Funny',
|
||||
'dob': '2025-04-08',
|
||||
}
|
||||
|
||||
sub_model_type = 'person'
|
||||
"""Sub Model Type
|
||||
|
||||
sub-models must have this attribute defined in `ModelName.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
def test_model_field_dob_optional(self):
|
||||
"""Test Field
|
||||
parameterized_fields: dict = {
|
||||
"f_name": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
},
|
||||
"m_name": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
},
|
||||
"l_name": {
|
||||
'field_type': models.fields.CharField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
},
|
||||
"dob": {
|
||||
'field_type': models.fields.DateField,
|
||||
'field_parameter_default_exists': False,
|
||||
'field_parameter_verbose_name_type': str,
|
||||
},
|
||||
}
|
||||
|
||||
Field `dob` must be an optional field
|
||||
|
||||
|
||||
def test_class_inherits_person(self):
|
||||
""" Class inheritence
|
||||
|
||||
TenancyObject must inherit SaveHistory
|
||||
"""
|
||||
|
||||
assert self.model._meta.get_field('dob').blank
|
||||
assert issubclass(self.model, Person)
|
||||
|
||||
|
||||
def test_model_field_f_name_mandatory(self):
|
||||
"""Test Field
|
||||
def test_attribute_value_history_app_label(self):
|
||||
"""Attribute Type
|
||||
|
||||
Field `f_name` must be a mandatory field
|
||||
history_app_label has been set, override this test case with the value
|
||||
of attribute `history_app_label`
|
||||
"""
|
||||
|
||||
assert(
|
||||
not (
|
||||
self.model._meta.get_field('f_name').blank
|
||||
and self.model._meta.get_field('f_name').null
|
||||
)
|
||||
and self.model._meta.get_field('f_name').default is NOT_PROVIDED
|
||||
)
|
||||
assert self.model.history_app_label == 'access'
|
||||
|
||||
|
||||
def test_model_field_l_name_mandatory(self):
|
||||
"""Test Field
|
||||
def test_attribute_value_history_model_name(self):
|
||||
"""Attribute Type
|
||||
|
||||
Field `l_name` must be a mandatory field
|
||||
history_model_name has been set, override this test case with the value
|
||||
of attribute `history_model_name`
|
||||
"""
|
||||
|
||||
assert (
|
||||
not (
|
||||
self.model._meta.get_field('l_name').blank
|
||||
and self.model._meta.get_field('l_name').null
|
||||
)
|
||||
and self.model._meta.get_field('l_name').default is NOT_PROVIDED
|
||||
)
|
||||
assert self.model.history_model_name == 'person'
|
||||
|
||||
|
||||
|
||||
def test_function_value_get_url(self):
|
||||
|
||||
assert self.item.get_url() == '/api/v2/access/entity/person/' + str(self.item.id)
|
||||
|
||||
|
||||
|
||||
class PersonModelInheritedCases(
|
||||
ModelTestCases,
|
||||
PersonModelTestCases,
|
||||
):
|
||||
"""Sub-Entity Test Cases
|
||||
"""Sub-Ticket Test Cases
|
||||
|
||||
Test Cases for Entity models that inherit from model Person
|
||||
Test Cases for Ticket models that inherit from model Entity
|
||||
"""
|
||||
|
||||
kwargs_item_create: dict = None
|
||||
kwargs_create_item: dict = {}
|
||||
|
||||
model = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(self):
|
||||
|
||||
self.kwargs_item_create.update(
|
||||
super().kwargs_item_create
|
||||
)
|
||||
|
||||
super().setUpTestData()
|
||||
sub_model_type = None
|
||||
"""Ticket Sub Model Type
|
||||
|
||||
Ticket sub-models must have this attribute defined in `ModelNam.Meta.sub_model_type`
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class PersonModelTest(
|
||||
ModelTestCases,
|
||||
TestCase,
|
||||
class PersonModelPyTest(
|
||||
PersonModelTestCases,
|
||||
):
|
||||
|
||||
pass
|
||||
|
||||
def test_function_value_get_related_model(self):
|
||||
"""Function test
|
||||
|
||||
Confirm function `get_related_model` is None for base model
|
||||
"""
|
||||
|
||||
assert self.item.get_related_model() is None
|
||||
|
@ -1,4 +1,6 @@
|
||||
from django.contrib.auth.models import Permission, User
|
||||
import django
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
@ -6,12 +8,14 @@ from django.test import Client, TestCase
|
||||
# from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.role import Role
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_fields import APITenancyObject
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class APITestCases(
|
||||
|
@ -1,22 +1,25 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
# from api.tests.abstract.api_permissions import APIPermissions
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamAPI(TestCase):
|
||||
|
@ -1,18 +1,21 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_fields import APITenancyObject
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamAPI(
|
||||
|
@ -1,6 +1,6 @@
|
||||
# from django.conf import settings
|
||||
import django
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase, Client
|
||||
@ -9,13 +9,15 @@ import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
from access.tests.abstract.model_permissions_organization_manager import OrganizationManagerModelPermissions
|
||||
|
||||
from app.tests.abstract.model_permissions import ModelPermissions
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamPermissions(
|
||||
|
@ -1,19 +1,22 @@
|
||||
import django
|
||||
import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_permissions import APIPermissions
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamPermissionsAPI(TestCase, APIPermissions):
|
||||
|
@ -1,18 +1,21 @@
|
||||
import django
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from rest_framework.relations import Hyperlink
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from api.tests.abstract.api_fields import APICommonFields
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamUserAPI(
|
||||
|
@ -7,7 +7,7 @@ import unittest
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# from django.conf import settings
|
||||
import django
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, Permission, User
|
||||
from django.contrib.auth.models import AnonymousUser, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase, Client
|
||||
@ -9,7 +9,7 @@ import pytest
|
||||
import unittest
|
||||
import requests
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
@ -17,6 +17,8 @@ from access.tests.abstract.model_permissions_organization_manager import Organiz
|
||||
|
||||
from app.tests.abstract.model_permissions import ModelPermissionsAdd, ModelPermissionsChange, ModelPermissionsDelete
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamUserPermissions(
|
||||
|
@ -1,12 +1,14 @@
|
||||
import django
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
from app.tests.unit.test_unit_models import NonTenancyObjectInheritedCases
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
|
||||
class TeamUsersModel(
|
||||
|
@ -7,7 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.test import TestCase
|
||||
from django.urls.exceptions import NoReverseMatch
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.tenancy import TenancyManager
|
||||
from access.models.tenancy import (
|
||||
TenancyObject,
|
||||
|
@ -4,7 +4,7 @@ from django.utils.decorators import method_decorator
|
||||
from django.views import generic
|
||||
|
||||
from access.mixin import *
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
|
||||
from access.forms.organization import OrganizationForm
|
||||
|
||||
@ -15,7 +15,7 @@ class IndexView(IndexView):
|
||||
|
||||
model = Organization
|
||||
permission_required = [
|
||||
'access.view_organization'
|
||||
'access.view_tenant'
|
||||
]
|
||||
template_name = 'access/index.html.j2'
|
||||
context_object_name = "organization_list"
|
||||
@ -61,7 +61,7 @@ class View(ChangeView):
|
||||
|
||||
return self.handle_no_permission()
|
||||
|
||||
if not self.permission_check(request, [ 'access.view_organization' ]):
|
||||
if not self.permission_check(request, [ 'access.view_tenant' ]):
|
||||
|
||||
raise PermissionDenied('You are not part of this organization')
|
||||
|
||||
@ -97,7 +97,7 @@ class View(ChangeView):
|
||||
|
||||
return self.handle_no_permission()
|
||||
|
||||
if not self.permission_check(request, [ 'access.change_organization' ]):
|
||||
if not self.permission_check(request, [ 'access.change_tenant' ]):
|
||||
|
||||
raise PermissionDenied('You are not part of this organization')
|
||||
|
||||
|
@ -5,7 +5,7 @@ from django.urls import reverse
|
||||
|
||||
from access.forms.team import TeamForm, TeamFormAdd
|
||||
from access.mixin import *
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
from access.models.team import Team
|
||||
from access.models.team_user import TeamUsers
|
||||
|
||||
|
@ -3,9 +3,9 @@ from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResp
|
||||
# THis import only exists so that the migrations can be created
|
||||
from access.models.organization_history import OrganizationHistory # pylint: disable=W0611:unused-import
|
||||
from access.serializers.organization import (
|
||||
Organization,
|
||||
OrganizationModelSerializer,
|
||||
OrganizationViewSerializer
|
||||
Tenant,
|
||||
TenantModelSerializer,
|
||||
TenantViewSerializer
|
||||
)
|
||||
|
||||
from api.viewsets.common import ModelViewSet
|
||||
@ -19,7 +19,7 @@ from api.viewsets.common import ModelViewSet
|
||||
description='',
|
||||
responses = {
|
||||
# 200: OpenApiResponse(description='Allready exists', response=OrganizationViewSerializer),
|
||||
201: OpenApiResponse(description='Created', response=OrganizationViewSerializer),
|
||||
201: OpenApiResponse(description='Created', response=TenantViewSerializer),
|
||||
# 400: OpenApiResponse(description='Validation failed.'),
|
||||
403: OpenApiResponse(description='User is missing add permissions'),
|
||||
}
|
||||
@ -36,7 +36,7 @@ from api.viewsets.common import ModelViewSet
|
||||
summary = 'Fetch all orgnaizations',
|
||||
description='',
|
||||
responses = {
|
||||
200: OpenApiResponse(description='', response=OrganizationViewSerializer),
|
||||
200: OpenApiResponse(description='', response=TenantViewSerializer),
|
||||
403: OpenApiResponse(description='User is missing view permissions'),
|
||||
}
|
||||
),
|
||||
@ -44,7 +44,7 @@ from api.viewsets.common import ModelViewSet
|
||||
summary = 'Fetch a single orgnaization',
|
||||
description='',
|
||||
responses = {
|
||||
200: OpenApiResponse(description='', response=OrganizationViewSerializer),
|
||||
200: OpenApiResponse(description='', response=TenantViewSerializer),
|
||||
403: OpenApiResponse(description='User is missing view permissions'),
|
||||
}
|
||||
),
|
||||
@ -53,7 +53,7 @@ from api.viewsets.common import ModelViewSet
|
||||
summary = 'Update an orgnaization',
|
||||
description = '',
|
||||
responses = {
|
||||
200: OpenApiResponse(description='', response=OrganizationViewSerializer),
|
||||
200: OpenApiResponse(description='', response=TenantViewSerializer),
|
||||
# 201: OpenApiResponse(description='Created', response=OrganizationViewSerializer),
|
||||
# # 400: OpenApiResponse(description='Validation failed.'),
|
||||
403: OpenApiResponse(description='User is missing change permissions'),
|
||||
@ -71,9 +71,9 @@ class ViewSet( ModelViewSet ):
|
||||
'name',
|
||||
]
|
||||
|
||||
model = Organization
|
||||
model = Tenant
|
||||
|
||||
view_description = 'Centurion Organizations'
|
||||
view_description = 'Centurion Tenants'
|
||||
|
||||
def get_serializer_class(self):
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiParameter, OpenApiResponse
|
||||
|
||||
from access.models.organization import Organization
|
||||
from access.models.tenant import Tenant as Organization
|
||||
# THis import only exists so that the migrations can be created
|
||||
from access.models.team_history import TeamHistory # pylint: disable=W0611:unused-import
|
||||
from access.serializers.teams import (
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user