from http import HTTPStatus from django.contrib.auth import get_user_model from django.test import Client, TestCase from django.urls import reverse from pytils.translit import slugify from notes.models import Note from notes.forms import WARNING class LogicTest(TestCase): @classmethod def setUpTestData(cls): cls.User = get_user_model() def setUp(self): self.client = Client() self.author = self.User.objects.create_user( username='author', password='password' ) self.author_client = Client() self.author_client.force_login(self.author) self.form_data = { 'title': 'Test Note', 'text': 'Test Text', 'slug': 'test-note' } self.note = Note.objects.create( title='Existing Note', text='Existing Text', slug='existing-note', author=self.author ) self.urls = { 'login': reverse('users:login'), 'signup': reverse('users:signup'), 'logout': reverse('users:logout'), 'home': reverse('notes:home'), 'add': reverse('notes:add'), 'edit': reverse('notes:edit', args=(self.note.slug,)), 'detail': reverse('notes:detail', args=(self.note.slug,)), 'delete': reverse('notes:delete', args=(self.note.slug,)), 'notes_list': reverse('notes:list'), 'success': reverse('notes:success'), } self.login_redirect_url = f'{self.urls["login"]}?next=' def test_user_can_create_note(self): url = self.urls['add'] initial_notes_count = Note.objects.count() response = self.author_client.post(url, data=self.form_data) self.assertRedirects(response, self.urls['success']) self.assertEqual(Note.objects.count(), initial_notes_count + 1) new_note = Note.objects.get(slug=self.form_data['slug']) self.assertEqual(new_note.title, self.form_data['title']) self.assertEqual(new_note.text, self.form_data['text']) self.assertEqual(new_note.slug, self.form_data['slug']) self.assertEqual(new_note.author, self.author) def test_anonymous_user_cant_create_note(self): url = self.urls['add'] initial_notes_count = Note.objects.count() response = self.client.post(url, data=self.form_data) expected_url = self.login_redirect_url + url self.assertRedirects(response, expected_url) self.assertEqual(Note.objects.count(), initial_notes_count) def test_not_unique_slug(self): url = self.urls['add'] self.form_data['slug'] = self.note.slug initial_notes_count = Note.objects.count() response = self.author_client.post(url, data=self.form_data) self.assertFormError( response, 'form', 'slug', errors=(self.note.slug + WARNING) ) self.assertEqual(Note.objects.count(), initial_notes_count) def test_empty_slug(self): url = self.urls['add'] self.form_data.pop('slug') initial_notes_count = Note.objects.count() response = self.author_client.post(url, data=self.form_data) self.assertRedirects(response, self.urls['success']) self.assertEqual(Note.objects.count(), initial_notes_count + 1) expected_slug = slugify(self.form_data['title']) new_note = Note.objects.get(slug=expected_slug) self.assertEqual(new_note.slug, expected_slug) self.assertEqual(Note.objects.filter(slug=expected_slug).count(), 1) def test_author_can_edit_note(self): url = self.urls['edit'] response = self.author_client.post(url, self.form_data) self.assertRedirects(response, self.urls['success']) self.note.refresh_from_db() self.assertEqual(self.note.title, self.form_data['title']) self.assertEqual(self.note.text, self.form_data['text']) self.assertEqual(self.note.slug, self.form_data['slug']) self.assertEqual(self.note.author, self.author) def test_other_user_cant_edit_note(self): other_user = self.User.objects.create_user( username='other', password='password' ) other_user_client = Client() other_user_client.force_login(other_user) url = reverse('notes:edit', args=(self.note.slug,)) response = other_user_client.post(url, self.form_data) self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) note_from_db = Note.objects.get(id=self.note.id) self.assertEqual(self.note.title, note_from_db.title) self.assertEqual(self.note.text, note_from_db.text) self.assertEqual(self.note.slug, note_from_db.slug) def test_author_can_delete_note(self): url = self.urls['delete'] initial_notes_count = Note.objects.count() response = self.author_client.post(url) self.assertRedirects(response, self.urls['success']) self.assertEqual(Note.objects.count(), initial_notes_count - 1) def test_other_user_cant_delete_note(self): other_user = self.User.objects.create_user( username='other', password='password' ) other_user_client = Client() other_user_client.force_login(other_user) url = reverse('notes:delete', args=(self.note.slug,)) initial_notes_count = Note.objects.count() response = other_user_client.post(url) self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) self.assertEqual(Note.objects.count(), initial_notes_count)