Module todo.tests.test_import

Expand source code
from django.urls import reverse
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils import timezone
import csv
from io import StringIO
from django.test import TestCase
from todo.models import List, ListItem
import datetime

class ImportTodoCSVTestCase(TestCase):
    def setUp(self):
        self.url = reverse('todo:import_todo_csv')

    # Utility function to generate CSV files for testing
    def generate_csv_file(self, rows):
        file = StringIO()
        writer = csv.writer(file)
        writer.writerow(['List Title', 'Item Name', 'Item Text', 'Is Done', 'Created On', 'Due Date'])
        writer.writerows(rows)
        file.seek(0)
        return SimpleUploadedFile("test.csv", file.read().encode('utf-8'), content_type="text/csv")

    def test_successful_import_with_minimal_data(self):
        csv_file = self.generate_csv_file([
            ['Minimal List', 'Minimal Item', 'Minimal Text', 'true', '2024-01-01', '2024-02-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(List.objects.filter(title_text="Minimal List").exists())
        self.assertTrue(ListItem.objects.filter(item_name="Minimal Item").exists())
    
    def test_successful_import_with_minimal_data(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Sample Item', 'Sample Text', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        
        # Verify redirection        
        print(response.status_code)
        self.assertEqual(response.status_code, 302)
        # Below one should be failing
        # self.assertRedirects(response, reverse('todo:index'))
        
        # Verify the ListItem was created as expected
        self.assertTrue(ListItem.objects.filter(item_name="Sample Item").exists())    

    def test_blank_is_done_field(self):
        csv_file = self.generate_csv_file([
            ['List Blank Is Done', 'Item Blank Is Done', 'Some Text', '', '2024-01-01', '2024-03-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(is_done=False).exists())

    def test_case_insensitive_boolean_in_is_done_field(self):
        csv_file = self.generate_csv_file([
            ['Case Insensitive Boolean List', 'Boolean Item', 'Boolean Text', 'TRUE', '2024-01-01', '2024-04-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(is_done=True).exists())

    def test_numeric_title_text_field(self):
        csv_file = self.generate_csv_file([
            ['12345', 'Item Numeric Title', 'Text for Numeric Title', 'false', '2024-01-01', '2024-04-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(List.objects.filter(title_text="12345").exists())

    def test_special_characters_in_item_name(self):
        csv_file = self.generate_csv_file([
            ['Special Char List', '@Special#Item!', 'Some text here', 'true', '2024-01-01', '2024-05-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="@Special#Item!").exists())  

    def test_multiple_rows_in_csv(self):
        csv_file = self.generate_csv_file([
            ['Multi List', 'Item One', 'Text One', 'true', '2024-01-01', '2024-04-01'],
            ['Multi List', 'Item Two', 'Text Two', 'false', '2024-01-02', '2024-05-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(List.objects.filter(title_text="Multi List").count(), 1)
        self.assertEqual(ListItem.objects.filter(list__title_text="Multi List").count(), 2)
        
    def test_successful_import_with_valid_data(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())
        
    def test_import_with_empty_csv(self):
        csv_file = self.generate_csv_file([])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(ListItem.objects.count(), 0)
        
    
    def test_import_with_all_false_is_done(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'false', '2024-10-01', '2024-12-01'],
            ['Test List', 'Item 2', 'Text for item 2', 'false', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(ListItem.objects.filter(is_done=False).count(), 2)
        
    def test_import_with_dates_only(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        item = ListItem.objects.get(item_name="Item 1")
        self.assertEqual(item.created_on.date(), datetime.date(2024, 10, 1))
        
    def test_import_with_missing_item_text(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', '', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())
        
    def test_import_with_non_boolean_is_done(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'maybe', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1", is_done=False).exists())
        
    def test_import_with_one_valid_row(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Single Item', 'Single Text', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Single Item").exists())
        

Classes

class ImportTodoCSVTestCase (methodName='runTest')

Similar to TransactionTestCase, but use transaction.atomic() to achieve test isolation.

In most situations, TestCase should be preferred to TransactionTestCase as it allows faster execution. However, there are some situations where using TransactionTestCase might be necessary (e.g. testing some transactional behavior).

On database backends with no transaction support, TestCase behaves as TransactionTestCase.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

Expand source code
class ImportTodoCSVTestCase(TestCase):
    def setUp(self):
        self.url = reverse('todo:import_todo_csv')

    # Utility function to generate CSV files for testing
    def generate_csv_file(self, rows):
        file = StringIO()
        writer = csv.writer(file)
        writer.writerow(['List Title', 'Item Name', 'Item Text', 'Is Done', 'Created On', 'Due Date'])
        writer.writerows(rows)
        file.seek(0)
        return SimpleUploadedFile("test.csv", file.read().encode('utf-8'), content_type="text/csv")

    def test_successful_import_with_minimal_data(self):
        csv_file = self.generate_csv_file([
            ['Minimal List', 'Minimal Item', 'Minimal Text', 'true', '2024-01-01', '2024-02-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(List.objects.filter(title_text="Minimal List").exists())
        self.assertTrue(ListItem.objects.filter(item_name="Minimal Item").exists())
    
    def test_successful_import_with_minimal_data(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Sample Item', 'Sample Text', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        
        # Verify redirection        
        print(response.status_code)
        self.assertEqual(response.status_code, 302)
        # Below one should be failing
        # self.assertRedirects(response, reverse('todo:index'))
        
        # Verify the ListItem was created as expected
        self.assertTrue(ListItem.objects.filter(item_name="Sample Item").exists())    

    def test_blank_is_done_field(self):
        csv_file = self.generate_csv_file([
            ['List Blank Is Done', 'Item Blank Is Done', 'Some Text', '', '2024-01-01', '2024-03-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(is_done=False).exists())

    def test_case_insensitive_boolean_in_is_done_field(self):
        csv_file = self.generate_csv_file([
            ['Case Insensitive Boolean List', 'Boolean Item', 'Boolean Text', 'TRUE', '2024-01-01', '2024-04-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(is_done=True).exists())

    def test_numeric_title_text_field(self):
        csv_file = self.generate_csv_file([
            ['12345', 'Item Numeric Title', 'Text for Numeric Title', 'false', '2024-01-01', '2024-04-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(List.objects.filter(title_text="12345").exists())

    def test_special_characters_in_item_name(self):
        csv_file = self.generate_csv_file([
            ['Special Char List', '@Special#Item!', 'Some text here', 'true', '2024-01-01', '2024-05-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="@Special#Item!").exists())  

    def test_multiple_rows_in_csv(self):
        csv_file = self.generate_csv_file([
            ['Multi List', 'Item One', 'Text One', 'true', '2024-01-01', '2024-04-01'],
            ['Multi List', 'Item Two', 'Text Two', 'false', '2024-01-02', '2024-05-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(List.objects.filter(title_text="Multi List").count(), 1)
        self.assertEqual(ListItem.objects.filter(list__title_text="Multi List").count(), 2)
        
    def test_successful_import_with_valid_data(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())
        
    def test_import_with_empty_csv(self):
        csv_file = self.generate_csv_file([])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(ListItem.objects.count(), 0)
        
    
    def test_import_with_all_false_is_done(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'false', '2024-10-01', '2024-12-01'],
            ['Test List', 'Item 2', 'Text for item 2', 'false', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertEqual(ListItem.objects.filter(is_done=False).count(), 2)
        
    def test_import_with_dates_only(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        item = ListItem.objects.get(item_name="Item 1")
        self.assertEqual(item.created_on.date(), datetime.date(2024, 10, 1))
        
    def test_import_with_missing_item_text(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', '', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())
        
    def test_import_with_non_boolean_is_done(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Item 1', 'Text for item 1', 'maybe', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Item 1", is_done=False).exists())
        
    def test_import_with_one_valid_row(self):
        csv_file = self.generate_csv_file([
            ['Test List', 'Single Item', 'Single Text', 'true', '2024-10-01', '2024-12-01']
        ])
        response = self.client.post(self.url, {'csv_file': csv_file})
        self.assertTrue(ListItem.objects.filter(item_name="Single Item").exists())

Ancestors

  • django.test.testcases.TestCase
  • django.test.testcases.TransactionTestCase
  • django.test.testcases.SimpleTestCase
  • unittest.case.TestCase

Methods

def generate_csv_file(self, rows)
Expand source code
def generate_csv_file(self, rows):
    file = StringIO()
    writer = csv.writer(file)
    writer.writerow(['List Title', 'Item Name', 'Item Text', 'Is Done', 'Created On', 'Due Date'])
    writer.writerows(rows)
    file.seek(0)
    return SimpleUploadedFile("test.csv", file.read().encode('utf-8'), content_type="text/csv")
def setUp(self)

Hook method for setting up the test fixture before exercising it.

Expand source code
def setUp(self):
    self.url = reverse('todo:import_todo_csv')
def test_blank_is_done_field(self)
Expand source code
def test_blank_is_done_field(self):
    csv_file = self.generate_csv_file([
        ['List Blank Is Done', 'Item Blank Is Done', 'Some Text', '', '2024-01-01', '2024-03-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(is_done=False).exists())
def test_case_insensitive_boolean_in_is_done_field(self)
Expand source code
def test_case_insensitive_boolean_in_is_done_field(self):
    csv_file = self.generate_csv_file([
        ['Case Insensitive Boolean List', 'Boolean Item', 'Boolean Text', 'TRUE', '2024-01-01', '2024-04-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(is_done=True).exists())
def test_import_with_all_false_is_done(self)
Expand source code
def test_import_with_all_false_is_done(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Item 1', 'Text for item 1', 'false', '2024-10-01', '2024-12-01'],
        ['Test List', 'Item 2', 'Text for item 2', 'false', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertEqual(ListItem.objects.filter(is_done=False).count(), 2)
def test_import_with_dates_only(self)
Expand source code
def test_import_with_dates_only(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    item = ListItem.objects.get(item_name="Item 1")
    self.assertEqual(item.created_on.date(), datetime.date(2024, 10, 1))
def test_import_with_empty_csv(self)
Expand source code
def test_import_with_empty_csv(self):
    csv_file = self.generate_csv_file([])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertEqual(ListItem.objects.count(), 0)
def test_import_with_missing_item_text(self)
Expand source code
def test_import_with_missing_item_text(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Item 1', '', 'true', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())
def test_import_with_non_boolean_is_done(self)
Expand source code
def test_import_with_non_boolean_is_done(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Item 1', 'Text for item 1', 'maybe', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(item_name="Item 1", is_done=False).exists())
def test_import_with_one_valid_row(self)
Expand source code
def test_import_with_one_valid_row(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Single Item', 'Single Text', 'true', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(item_name="Single Item").exists())
def test_multiple_rows_in_csv(self)
Expand source code
def test_multiple_rows_in_csv(self):
    csv_file = self.generate_csv_file([
        ['Multi List', 'Item One', 'Text One', 'true', '2024-01-01', '2024-04-01'],
        ['Multi List', 'Item Two', 'Text Two', 'false', '2024-01-02', '2024-05-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertEqual(List.objects.filter(title_text="Multi List").count(), 1)
    self.assertEqual(ListItem.objects.filter(list__title_text="Multi List").count(), 2)
def test_numeric_title_text_field(self)
Expand source code
def test_numeric_title_text_field(self):
    csv_file = self.generate_csv_file([
        ['12345', 'Item Numeric Title', 'Text for Numeric Title', 'false', '2024-01-01', '2024-04-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(List.objects.filter(title_text="12345").exists())
def test_special_characters_in_item_name(self)
Expand source code
def test_special_characters_in_item_name(self):
    csv_file = self.generate_csv_file([
        ['Special Char List', '@Special#Item!', 'Some text here', 'true', '2024-01-01', '2024-05-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(item_name="@Special#Item!").exists())  
def test_successful_import_with_minimal_data(self)
Expand source code
def test_successful_import_with_minimal_data(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Sample Item', 'Sample Text', 'true', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    
    # Verify redirection        
    print(response.status_code)
    self.assertEqual(response.status_code, 302)
    # Below one should be failing
    # self.assertRedirects(response, reverse('todo:index'))
    
    # Verify the ListItem was created as expected
    self.assertTrue(ListItem.objects.filter(item_name="Sample Item").exists())    
def test_successful_import_with_valid_data(self)
Expand source code
def test_successful_import_with_valid_data(self):
    csv_file = self.generate_csv_file([
        ['Test List', 'Item 1', 'Text for item 1', 'true', '2024-10-01', '2024-12-01']
    ])
    response = self.client.post(self.url, {'csv_file': csv_file})
    self.assertTrue(ListItem.objects.filter(item_name="Item 1").exists())