Andrew Smirnov ee2959e16a
Merge branch 'develop' into feature/react_test
# Conflicts:
#	main/tests.py
2021-05-20 20:23:27 +03:00

552 lines
26 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
from unittest.mock import patch, Mock
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
from django.core import mail
from django.http import HttpResponseRedirect
from django.template.loader import render_to_string
from django.test import TestCase, Client
from django.urls import reverse, reverse_lazy
from django.utils import translation, timezone
import access_controller.settings as sets
from main.zendesk_admin import zenpy
from main.extra_func import log
class UsersBaseTestCase(TestCase):
"""Базовый класс загружения данных для тестов с пользователями"""
fixtures = ['fixtures/test_users.json']
def setUp(self):
"""Добавление в переменные почт и клиентов для пользователей"""
self.light_agent = '123@test.ru'
self.admin = 'admin@gmail.com'
self.engineer = 'customer@example.com'
self.agent_client = Client()
self.agent_client.force_login(User.objects.get(email=self.light_agent))
self.admin_client = Client()
self.admin_client.force_login(User.objects.get(email=self.admin))
self.engineer_client = Client()
self.engineer_client.force_login(User.objects.get(email=self.engineer))
class RegistrationTestCase(TestCase):
fixtures = ['fixtures/data.json']
def setUp(self):
self.email_backend = 'django.core.mail.backends.locmem.EmailBackend'
self.any_zendesk_user_email = 'idar.sokurov.05@mail.ru'
self.zendesk_admin_email = 'idar.sokurov.05@mail.ru'
self.client = Client()
def test_registration_complete_redirect(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
resp = self.client.post(reverse('registration'), data={'email': self.any_zendesk_user_email})
self.assertRedirects(resp, reverse('password_reset_done'))
def test_registration_fail_redirect(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
resp = self.client.post(reverse('registration'), data={'email': self.any_zendesk_user_email + 'asd'})
self.assertRedirects(resp, reverse('django_registration_disallowed'))
def test_registration_user_already_exist(self):
with self.settings(EMAIL_BACKEND=self.email_backend) and translation.override('ru'):
resp = self.client.post(reverse('registration'), data={'email': '123@test.ru'})
self.assertContains(resp, 'Этот адрес электронной почты уже используется', count=1, status_code=200)
def test_registration_send_email(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
response: HttpResponseRedirect = \
self.client.post(reverse('registration'), data={'email': self.any_zendesk_user_email})
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, [self.any_zendesk_user_email])
# context that the email template was rendered with
email_context = response.context[0].dicts[1]
correct_subject = render_to_string('registration/password_reset_subject.txt', email_context, response.request)
self.assertEqual(mail.outbox[0].subject, correct_subject.strip())
correct_body = render_to_string('registration/password_reset_email.html', email_context, response.request)
self.assertEqual(mail.outbox[0].body, correct_body)
def test_registration_user_creating(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
self.client.post(reverse('registration'), data={'email': self.any_zendesk_user_email})
user = User.objects.get(email=self.any_zendesk_user_email)
zendesk_user = zenpy.get_user(self.any_zendesk_user_email)
self.assertEqual(user.userprofile.name, zendesk_user.name)
def test_permissions_applying(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
self.client.post(reverse('registration'), data={'email': self.zendesk_admin_email})
user = User.objects.get(email=self.zendesk_admin_email)
self.assertEqual(user.userprofile.role, 'admin')
self.assertTrue(user.has_perm('main.has_control_access'))
class MakeEngineerTestCase(UsersBaseTestCase):
@patch('main.extra_func.zenpy')
def test_become_engineer_redirect(self, _zenpy_mock):
user = User.objects.get(email=self.light_agent)
resp = self.agent_client.post(reverse_lazy('work_become_engineer'))
self.assertRedirects(resp, reverse('work', args=[user.id]))
self.assertEqual(resp.status_code, 302)
@patch('main.extra_func.zenpy')
def test_light_agent_make_engineer(self, zenpy_mock):
self.agent_client.post(reverse_lazy('work_become_engineer'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['engineer'])
@patch('main.extra_func.zenpy')
def test_admin_make_engineer(self, zenpy_mock):
self.admin_client.post(reverse_lazy('work_become_engineer'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['engineer'])
@patch('main.extra_func.zenpy')
def test_engineer_make_engineer(self, zenpy_mock):
self.engineer_client.post(reverse_lazy('work_become_engineer'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['engineer'])
@patch('main.extra_func.zenpy')
def test_control_page_make_engineer_one(self, zenpy_mock):
self.admin_client.post(
reverse_lazy('control'),
data={'users': [User.objects.get(email=self.light_agent).userprofile.id], 'engineer': 'engineer'}
)
call_list = zenpy_mock.update_user.call_args_list
mock_object = call_list[0][0][0]
self.assertEqual(len(call_list), 1)
self.assertEqual(mock_object.custom_role_id, sets.ZENDESK_ROLES['engineer'])
@patch('main.extra_func.zenpy')
def test_control_page_make_engineer_many(self, zenpy_mock):
self.admin_client.post(
reverse_lazy('control'),
data={
'users': [
User.objects.get(email=self.light_agent).userprofile.id,
User.objects.get(email=self.engineer).userprofile.id,
],
'engineer': 'engineer'
}
)
call_list = zenpy_mock.update_user.call_args_list
mock_objects = list(call_list)
self.assertEqual(len(call_list), 2)
for obj in mock_objects:
self.assertEqual(obj[0][0].custom_role_id, sets.ZENDESK_ROLES['engineer'])
class MakeLightAgentTestCase(UsersBaseTestCase):
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[]])
@patch('main.extra_func.zenpy')
def test_hand_over_redirect(self, _zenpy_mock, _user_tickets_mock):
user = User.objects.get(email=self.engineer)
resp = self.engineer_client.post(reverse_lazy('work_hand_over'))
self.assertRedirects(resp, reverse('work', args=[user.id]))
self.assertEqual(resp.status_code, 302)
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[]])
@patch('main.extra_func.zenpy')
def test_engineer_make_light_agent_no_tickets(self, zenpy_mock, _user_tickets_mock):
self.engineer_client.post(reverse_lazy('work_hand_over'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[
[Mock(id=1, status='solved'), Mock(id=2, status='open'), Mock(id=3, status='open')]
])
@patch('main.extra_func.zenpy')
def test_engineer_make_light_agent_with_tickets(self, zenpy_mock, _user_tickets_mock):
zenpy_mock.solved_tickets_user_id = Mock()
self.engineer_client.post(reverse_lazy('work_hand_over'))
tickets_update = zenpy_mock.admin.tickets.update.call_args[0][0]
self.assertEqual(tickets_update[0].assignee_id, zenpy_mock.solved_tickets_user_id)
self.assertIsNone(tickets_update[1].assignee)
self.assertIsNone(tickets_update[2].assignee)
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[]])
@patch('main.extra_func.zenpy')
def test_admin_make_light_agent_no_tickets(self, zenpy_mock, _user_tickets_mock):
self.admin_client.post(reverse_lazy('work_hand_over'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[
[Mock(id=1, status='solved'), Mock(id=2, status='open'), Mock(id=3, status='open')]
])
@patch('main.extra_func.zenpy')
def test_admin_make_light_agent_with_tickets(self, zenpy_mock, _user_tickets_mock):
zenpy_mock.solved_tickets_user_id = Mock()
self.admin_client.post(reverse_lazy('work_hand_over'))
tickets_update = zenpy_mock.admin.tickets.update.call_args[0][0]
self.assertEqual(tickets_update[0].assignee_id, zenpy_mock.solved_tickets_user_id)
self.assertIsNone(tickets_update[1].assignee)
self.assertIsNone(tickets_update[2].assignee)
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[]])
@patch('main.extra_func.zenpy')
def test_light_agent_make_light_agent(self, zenpy_mock, _user_tickets_mock):
self.agent_client.post(reverse_lazy('work_hand_over'))
self.assertEqual(zenpy_mock.update_user.call_args[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[]])
@patch('main.extra_func.zenpy')
def test_control_page_make_light_agent_one(self, zenpy_mock, _user_tickets_mock):
self.admin_client.post(
reverse_lazy('control'),
data={'users': [User.objects.get(email=self.engineer).userprofile.id], 'light_agent': 'light_agent'}
)
call_list = zenpy_mock.update_user.call_args_list
mock_object = call_list[0][0][0]
self.assertEqual(len(call_list), 1)
self.assertEqual(mock_object.custom_role_id, sets.ZENDESK_ROLES['light_agent'])
@patch('main.requester.TicketListRequester.get_tickets_list_for_user', side_effect=[[], []])
@patch('main.extra_func.zenpy')
def test_control_page_make_light_agent_many(self, zenpy_mock, _user_tickets_mock):
self.admin_client.post(
reverse_lazy('control'),
data={
'users': [
User.objects.get(email=self.light_agent).userprofile.id,
User.objects.get(email=self.engineer).userprofile.id,
],
'light_agent': 'light_agent'
}
)
call_list = zenpy_mock.update_user.call_args_list
mock_objects = list(call_list)
self.assertEqual(len(call_list), 2)
for obj in mock_objects:
self.assertEqual(obj[0][0].custom_role_id, sets.ZENDESK_ROLES['light_agent'])
class PasswordResetTestCase(UsersBaseTestCase):
def setUp(self):
super().setUp()
self.email_backend = 'django.core.mail.backends.locmem.EmailBackend'
def test_redirect(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
resp = self.agent_client.post(reverse_lazy('password_reset'), data={'email': self.light_agent})
self.assertRedirects(resp, reverse('password_reset_done'))
self.assertEqual(resp.status_code, 302)
def test_send_email(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
response: HttpResponseRedirect = \
self.agent_client.post(reverse_lazy('password_reset'), data={'email': self.light_agent})
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, [self.light_agent])
# context that the email template was rendered with
email_context = response.context[0].dicts[1]
correct_subject = render_to_string('registration/password_reset_subject.txt', email_context, response.request)
self.assertEqual(mail.outbox[0].subject, correct_subject.strip())
correct_body = render_to_string('registration/password_reset_email.html', email_context, response.request)
self.assertEqual(mail.outbox[0].body, correct_body)
def test_email_invalid(self):
with self.settings(EMAIL_BACKEND=self.email_backend) and translation.override('ru'):
resp = self.agent_client.post(reverse_lazy('password_reset'), data={'email': 1})
self.assertContains(resp, 'Введите правильный адрес электронной почты.', count=1, status_code=200)
def test_user_does_not_exist(self):
with self.settings(EMAIL_BACKEND=self.email_backend):
resp = self.agent_client.post(reverse_lazy('password_reset'), data={'email': self.light_agent + str(random.random())})
self.assertRedirects(resp, reverse('password_reset_done'))
self.assertEqual(resp.status_code, 302)
self.assertEqual(len(mail.outbox), 0)
class PasswordChangeTestCase(UsersBaseTestCase):
def setUp(self):
super().setUp()
self.set_password()
def set_password(self):
user: User = User.objects.get(email=self.light_agent)
user.set_password('ImpossiblyHardPassword')
user.save()
self.agent_client.force_login(User.objects.get(email=self.light_agent))
def test_change_successful(self):
self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'ImpossiblyHardPassword',
'new_password1': 'EasyPassword',
'new_password2': 'EasyPassword',
}
)
user = User.objects.get(email=self.light_agent)
self.assertTrue(user.check_password('EasyPassword'))
def test_invalid_old_password(self):
with translation.override('ru'):
resp = self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'EasyPassword',
'new_password1': 'EasyPassword',
'new_password2': 'EasyPassword',
}
)
self.assertContains(resp, 'Ваш старый пароль введен неправильно', count=1, status_code=200)
def test_different_new_passwords(self):
with translation.override('ru'):
resp = self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'ImpossiblyHardPassword',
'new_password1': 'EasyPassword',
'new_password2': 'EasyPassword1',
}
)
self.assertContains(resp, 'Введенные пароли не совпадают', count=1, status_code=200)
def test_invalid_new_password1(self):
with translation.override('ru'):
resp = self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'ImpossiblyHardPassword',
'new_password1': 'short',
'new_password2': 'short',
}
)
self.assertContains(resp, 'Введённый пароль слишком короткий', count=1, status_code=200)
def test_invalid_new_password2(self):
with translation.override('ru'):
resp = self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'ImpossiblyHardPassword',
'new_password1': '123123123123123123132123123',
'new_password2': '123123123123123123132123123',
}
)
self.assertContains(resp, 'Введённый пароль состоит только из цифр', count=1, status_code=200)
def test_invalid_new_password3(self):
with translation.override('ru'):
resp = self.agent_client.post(
reverse_lazy('password_change'),
data={
'old_password': 'ImpossiblyHardPassword',
'new_password1': self.light_agent,
'new_password2': self.light_agent,
}
)
self.assertContains(resp, 'Введённый пароль слишком похож на имя пользователя', count=1, status_code=200)
class GetTicketsTestCase(UsersBaseTestCase):
"""
Класс тестов для проверки функции получения тикетов.
"""
@patch('main.views.zenpy.get_user')
@patch('main.extra_func.zenpy')
def test_redirect(self, _zenpy_mock, get_user_mock):
"""
Функция проверки переадресации пользователя на рабочую страницу.
"""
get_user_mock.return_value = Mock()
user = User.objects.get(email=self.engineer)
resp = self.engineer_client.post(reverse('work_get_tickets'))
self.assertRedirects(resp, reverse('work', args=[user.id]))
self.assertEqual(resp.status_code, 302)
@patch('main.views.zenpy')
@patch('main.views.get_tickets_list_for_group')
def test_take_one_ticket(self, group_tickets_mock, zenpy_mock):
"""
Функция проверки назначения одного тикета на engineer.
"""
group_tickets_mock.return_value = [Mock()]
zenpy_mock.get_user.return_value = Mock(role='agent', custom_role_id=sets.ZENDESK_ROLES['engineer'])
self.engineer_client.post(reverse('work_get_tickets'), data={'count_tickets': 1})
tickets = zenpy_mock.update_tickets.call_args
self.assertEqual(tickets[0][0][0].assignee, zenpy_mock.get_user.return_value)
@patch('main.views.get_tickets_list_for_group')
@patch('main.views.zenpy')
def test_take_many_tickets(self, zenpy_mock, group_tickets_mock):
"""
Функция проверки назначения нескольких тикетов на engineer.
"""
group_tickets_mock.return_value = [Mock()] * 3
zenpy_mock.get_user.return_value = Mock(role='agent', custom_role_id=sets.ZENDESK_ROLES['engineer'])
self.engineer_client.post(reverse('work_get_tickets'), data={'count_tickets': 3})
tickets = zenpy_mock.update_tickets.call_args
for ticket in tickets[0][0]:
self.assertEqual(ticket.assignee, zenpy_mock.get_user.return_value)
@patch('main.views.zenpy.get_user')
@patch('main.views.zenpy')
def test_light_agent_take_ticket(self, zenpy_mock, get_user_mock):
"""
Функция проверки попытки назначения тикета на light_agent.
"""
get_user_mock.return_value = Mock(role='agent', custom_role_id=sets.ZENDESK_ROLES['light_agent'])
self.agent_client.post(reverse('work_get_tickets'), data={'count_tickets': 3})
tickets = zenpy_mock.update_tickets.call_args
self.assertIsNone(tickets)
@patch('main.views.zenpy')
@patch('main.views.get_tickets_list_for_group')
def test_take_zero_tickets(self, TicketsMock, zenpy_mock):
"""
Функция проверки попытки назначения нуля тикета на engineer.
"""
TicketsMock.return_value = [Mock()] * 3
zenpy_mock.get_user.return_value = Mock(role='agent', custom_role_id=sets.ZENDESK_ROLES['engineer'])
self.engineer_client.post(reverse('work_get_tickets'), data={'count_tickets': 0})
tickets = zenpy_mock.update_tickets.call_args[0][0]
self.assertListEqual(tickets, [])
@patch('main.views.get_tickets_list_for_group')
@patch('main.views.zenpy')
def test_take_invalid_count_tickets(self, zenpy_mock, group_tickets_mock):
"""
Функция проверки попытки назначения нуля тикетов на engineer.
"""
group_tickets_mock.return_value = [Mock()] * 3
zenpy_mock.get_user.return_value = Mock(role='agent', custom_role_id=sets.ZENDESK_ROLES['engineer'])
self.engineer_client.post(reverse('work_get_tickets'), data={'count_tickets': 'asd'})
tickets = zenpy_mock.update_tickets.call_args
self.assertIsNone(tickets)
class ProfileTestCase(TestCase):
"""
Класс тестов для проверки синхронизации профиля пользователя.
"""
fixtures = ['fixtures/profile.json']
def setUp(self):
"""
Предустановленные значения для проведения тестов.
"""
self.zendesk_agent_email = 'krav-88@mail.ru'
self.zendesk_admin_email = 'idar.sokurov.05@mail.ru'
self.client = Client()
self.client.force_login(User.objects.get(email=self.zendesk_agent_email))
self.admin_client = Client()
self.admin_client.force_login(User.objects.get(email=self.zendesk_admin_email))
def test_correct_username(self):
"""
Функция проверки синхронизации имени пользователя.
"""
resp = self.client.get(reverse('profile'))
self.assertEqual(resp.context['profile'].name, zenpy.get_user(self.zendesk_agent_email).name)
def test_correct_email(self):
"""
Функция проверки синхронизации почты пользователя.
"""
resp = self.client.get(reverse('profile'))
self.assertEqual(resp.context['profile'].user.email, zenpy.get_user(self.zendesk_agent_email).email)
def test_correct_role(self):
"""
Функция проверки синхронизации роли пользователя.
"""
resp = self.client.get(reverse('profile'))
self.assertEqual(resp.context['profile'].role, zenpy.get_user(self.zendesk_agent_email).role)
resp = self.admin_client.get(reverse('profile'))
self.assertEqual(resp.context['profile'].role, zenpy.get_user(self.zendesk_admin_email).role)
def test_correct_custom_role_id(self):
"""
Функция проверки синхронизации рабочей роли пользователя.
"""
resp = self.client.get(reverse('profile'))
user = zenpy.get_user(self.zendesk_agent_email)
self.assertEqual(resp.context['profile'].custom_role_id, user.custom_role_id if user.custom_role_id else 0)
resp = self.admin_client.get(reverse('profile'))
user = zenpy.get_user(self.zendesk_admin_email)
self.assertEqual(resp.context['profile'].custom_role_id, user.custom_role_id if user.custom_role_id else 0)
def test_correct_image(self):
"""
Функция проверки синхронизации изображения пользователя.
"""
resp = self.client.get(reverse('profile'))
user = zenpy.get_user(self.zendesk_agent_email)
self.assertEqual(resp.context['profile'].image, user.photo['content_url'] if user.photo else None)
class LoggingTestCase(UsersBaseTestCase):
def setUp(self):
super().setUp()
self.admin_profile = User.objects.get(email=self.admin).userprofile
self.agent_profile = User.objects.get(email=self.light_agent).userprofile
self.engineer_profile = User.objects.get(email=self.engineer).userprofile
@staticmethod
def get_file_output():
file = open('logs/logs.csv', 'r')
file_output = file.readlines()[-1]
file.close()
return file_output
def test_engineer_with_admin(self):
log(self.engineer_profile, self.admin_profile)
file_output = self.get_file_output()
self.assertEqual(file_output, f'UserForAccessTest,engineer,'
f'{str(timezone.now().today())[:16]},ZendeskAdmin\n')
def test_engineer_without_admin(self):
log(self.engineer_profile)
file_output = self.get_file_output()
self.assertEqual(file_output, f'UserForAccessTest,engineer,'
f'{str(timezone.now().today())[:16]},UserForAccessTest\n')
def test_light_agent_with_admin(self):
log(self.agent_profile, self.admin_profile)
file_output = self.get_file_output()
self.assertEqual(file_output, f'UserForAccessTest,light_agent,'
f'{str(timezone.now().today())[:16]},ZendeskAdmin\n')
def test_light_agent_without_admin(self):
log(self.agent_profile)
file_output = self.get_file_output()
self.assertEqual(file_output, f'UserForAccessTest,light_agent,'
f'{str(timezone.now().today())[:16]},UserForAccessTest\n')
class ControlAccessTests(TestCase):
fixtures = ['test_data_base.json']
def setUp(self) -> None:
self.User = get_user_model()
self.client = Client()
def test_admin_has_perm(self):
self.client.force_login(self.User.objects.get(email='admin@gmail.com'))
self.response = self.client.get(reverse('control'))
self.assertEqual(self.response.status_code, 200)
def test_engineer_doesnt_have_perm(self):
self.client.force_login(self.User.objects.get(email='123@test.ru'))
self.response = self.client.get(reverse('control'))
self.assertEqual(self.response.status_code, 403)