import json from unittest import skip from unittest.mock import patch from django.contrib.auth.models import User from django.test import TestCase, Client, SimpleTestCase from django.urls import reverse from django_models_from_csv import models as csv_models from django_models_from_csv.commands.manage_py import ( make_and_apply_migrations ) from django_models_from_csv.models import DynamicModel, create_models from django_models_from_csv.utils.common import get_setting # from django.db import DEFAULT_DB_ALIAS, connections, transaction CSV = """Timestamp,Question with short answer?,Question with long answer?,Checkbox?,Option with dropdown?,Multiple choice?, Numeric linear scale?,Multiple choice grid? [row1],Multiple choice grid? [row2],Checkbox grid? [row1],Checkbox grid? [row2],What date?,What time? 4/8/2019 20:43:03,This is a short answer.,This is a suuuuuuuuuuuppperrr long answer. I could repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it repeat it.,The option,OPT2,Lol,4,col1,col2,col2,col1,4/9/2019,10:01:00 PM""" COLUMNS = [ { "name": "timestamp", "original_name": "Timestamp", "type": "datetime", "attrs": { "blank": True, "null": True } }, { "name": "question_with_short_answer_field", "original_name": "Question with short answer?", "type": "text", "attrs": {} }, { "name": "question_with_long_answer_field", "original_name": "Question with long answer?", "type": "text", "attrs": {} }, { "name": "checkbox_field", "original_name": "Checkbox?", "type": "text", "attrs": {} }, { "name": "option_with_dropdown_field", "original_name": "Option with dropdown?", "type": "text", "attrs": {} }, { "name": "multiple_choice_field", "original_name": "Multiple choice?", "type": "text", "attrs": {} }, { "name": "field_numeric_linear_scale_field", "original_name": " Numeric linear scale?", "type": "text", "attrs": {} }, { "name": "multiple_choice_grid_row1_field", "original_name": "Multiple choice grid? [row1]", "type": "text", "attrs": {} }, { "name": "multiple_choice_grid_row2_field", "original_name": "Multiple choice grid? [row2]", "type": "text", "attrs": {} }, { "name": "checkbox_grid_row1_field", "original_name": "Checkbox grid? [row1]", "type": "text", "attrs": {} }, { "name": "checkbox_grid_row2_field", "original_name": "Checkbox grid? [row2]", "type": "text", "attrs": {} }, { "name": "what_date_field", "original_name": "What date?", "type": "date", "attrs": {} }, { "name": "what_time_field", "original_name": "What time?", "type": "text", "attrs": {} } ] class ViewsTestCaseBase(SimpleTestCase): databases = "__all__" def login(self): self.client.login(username="admin", password=self.password) def setUp(self): self.password = User.objects.make_random_password(length=16) self.user = User.objects.create_superuser( username="admin", password=self.password, email="admin@localhost", ) self.user.save() self.login() def tearDown(self): self.user.delete() class BeginViewTestCase(ViewsTestCaseBase): def setUp(self): super(BeginViewTestCase, self).setUp() self.csv = CSV def tearDown(self): super(BeginViewTestCase, self).tearDown() DynamicModel.objects.all().delete() def test_can_access_begin_csv_model_page_authed(self): self.login() url = reverse('csv_models:begin') url += "?addnew=true" response = self.client.get(url) self.assertEqual(response.status_code, 200) def test_cannot_access_begin_csv_model_page_unauthed(self): c = Client() response = c.get(reverse('csv_models:begin')) self.assertEqual(response.status_code, 302) @patch("django_models_from_csv.utils.dynmodel.fetch_csv") def test_can_start_new_csv_model(self, fetch_csv): fetch_csv.return_value = self.csv ids = DynamicModel.objects.all().values("id") response = self.client.post(reverse('csv_models:begin'), { "csv_name": "TestSheet", "csv_url": "https://fake.url", }) new_dynmodel = DynamicModel.objects.first() to_url = reverse( 'csv_models:refine-and-import', args=[new_dynmodel.id] ) self.assertTrue(new_dynmodel.columns) self.assertGreaterEqual(len(new_dynmodel.columns), 13) self.assertRedirects(response, to_url) new_dynmodel.delete() # @patch("django_models_from_csv.utils.dynmodel.ScreendoorImporter") # def test_can_build_model_from_screendoor(self, fetch_csv): # fetch_csv.return_value = self.csv # ids = DynamicModel.objects.all().values("id") # response = self.client.post(reverse('csv_models:begin'), { # "name": "TestScreendoor", # "sd_api_key": "KEY", # "sd_project_id": "PROJECT_ID", # "sd_form_id": "FORM_ID", # }) # new_dynmodel = DynamicModel.objects.last() # to_url = reverse( # 'csv_models:refine-and-import', args=[new_dynmodel.id] # ) # self.assertTrue(new_dynmodel.columns) # self.assertGreaterEqual(len(new_dynmodel.columns), 13) # self.assertRedirects(response, to_url) # new_dynmodel.delete() class RefineViewTestCase(ViewsTestCaseBase): databases = "__all__" def setUp(self): super(RefineViewTestCase, self).setUp() self.columns = [ { "name": "timestamp", "original_name": "Timestamp", "type": "text", "attrs": { "blank": True, "null": True } }, { "name": "question_with_short_answer_field", "original_name": "Question with short answer?", "type": "text", "attrs": {} }, { "name": "question_with_long_answer_field", "original_name": "Question with long answer?", "type": "text", "attrs": {} }, { "name": "checkbox_field", "original_name": "Checkbox?", "type": "text", "attrs": {} }, { "name": "option_with_dropdown_field", "original_name": "Option with dropdown?", "type": "text", "attrs": {} }, { "name": "multiple_choice_field", "original_name": "Multiple choice?", "type": "text", "attrs": {} }, { "name": "field_numeric_linear_scale_field", "original_name": " Numeric linear scale?", "type": "text", "attrs": {} }, { "name": "multiple_choice_grid_row1_field", "original_name": "Multiple choice grid? [row1]", "type": "text", "attrs": {} }, { "name": "multiple_choice_grid_row2_field", "original_name": "Multiple choice grid? [row2]", "type": "text", "attrs": {} }, { "name": "checkbox_grid_row1_field", "original_name": "Checkbox grid? [row1]", "type": "text", "attrs": {} }, { "name": "checkbox_grid_row2_field", "original_name": "Checkbox grid? [row2]", "type": "text", "attrs": {} }, { "name": "what_date_field", "original_name": "What date?", "type": "date", "attrs": {} }, { "name": "what_time_field", "original_name": "What time?", "type": "text", "attrs": {} } ] self.dynmodel = DynamicModel.objects.create( name="RefineTest", csv_url="https://refine.test/csv", columns=self.columns, ) self.dynmodel.save() def tearDown(self): super(RefineViewTestCase, self).tearDown() self.dynmodel.delete() def test_can_access_refine_page_authed(self): to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) response = self.client.get(to_url) self.assertEqual(response.status_code, 200) def test_cannot_access_refine_page_unauthed(self): c = Client() to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) response = c.get(to_url) self.assertEqual(response.status_code, 302) @patch("django_models_from_csv.views.configuration.fetch_csv") def test_can_refine_existing_model(self, fetch_csv): fetch_csv.return_value = CSV to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) to_url += "?next=/next/url" self.assertEqual(self.dynmodel.columns[0]["type"], "text") self.columns[0]["type"] = "datetime" response = self.client.post(to_url, { "columns": json.dumps(self.columns), }) next = get_setting("CSV_MODELS_WIZARD_REDIRECT_TO") if next: self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith(next)) else: self.assertEqual(response.status_code, 200) # make sure the field was actually updated self.dynmodel.refresh_from_db() self.assertEqual(self.dynmodel.columns[0]["type"], "datetime") class ImportViewTestCase(ViewsTestCaseBase): def setUp(self): super(ImportViewTestCase, self).setUp() self.csv = CSV self.columns = COLUMNS self.err_string = "errors were encountered while importing" # column with some changes (timestamp: text -> datetime) self.dynmodel = DynamicModel.objects.create( name="ImportViewTest", csv_url="https://import.test/csv", columns=self.columns, ) self.dynmodel.save() create_models() def tearDown(self): super(ImportViewTestCase, self).tearDown() self.dynmodel.delete() def test_can_access_import_page_authed(self): to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) response = self.client.get(to_url) self.assertEqual(response.status_code, 200) def test_cannot_access_import_page_unauthed(self): c = Client() to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) response = c.get(to_url) self.assertEqual(response.status_code, 302) @skip("Until we can get the dynamic models created in test") @patch("django_models_from_csv.views.configuration.fetch_csv") def test_can_load_import_records_page(self, fetch_csv): fetch_csv.return_value = self.csv to_url = reverse( 'csv_models:refine-and-import', args=[self.dynmodel.id] ) response = self.client.post(to_url, { "columns": json.dumps(self.columns), }) self.assertEqual(response.status_code, 200) err_found = self.err_string in str(response.content) self.assertTrue(not err_found, "Import rendered error page") #class NoTransactionImportDataTestCase(SimpleTestCase): # databases = "__all__" # # def test_can_import_records(self): # dynmodel = DynamicModel.objects.create( # name="ImportDataTest", # csv_url="https://import.test/csv", # columns=COLUMNS, # ) # dynmodel.save() # create_models() # # # connection = connections[DEFAULT_DB_ALIAS] # # connection.disable_constraint_checking() # create_models() # make_and_apply_migrations() # # # make sure the field was actually updated # Model = getattr(csv_models, dynmodel.name) # self.assertEqual(Model.objects.count(), 1)