def test_adding_a_profile_image(self): # Start with no UserInfo, thus no profile pic self.assertFalse(UserInfo.objects.filter(user_id=self.user.id)) myClient = Client() myClient.force_login(user=self.user) # Set up registration form data photo = create_image(None, 'photo.png') photo_file = BytesIO(photo.getvalue()) photo_file.name = 'photo.png' form_data = { 'profile_photo': photo_file, 'x': 0, 'y': 0, 'width': 0, 'height': 0, 'first_name': 'Julie', 'last_name': 'Apple', 'email': '*****@*****.**', 'about_me': 'someone will read this' } # Ensure new userinfo is written since we're not exactly using the HTTP engine. response = myClient.post(reverse('lmn:my_user_profile'), form_data) ##self.assertRegex(response.redirect_chain[0][0], r'/users/profile/$') # And now there is a user profile with a profile pic self.assertIsNotNone( UserInfo.objects.filter(user_id=self.user.id).get().user_photo)
def get_staff_client(): user = User.objects.create_user('*****@*****.**', 'pw') change_candidate_perm = Permission.objects.get(codename='change_candidate') user.user_permissions.add(change_candidate_perm) staff_client = Client() staff_client.force_login(user) return staff_client
def admin_django_client(): admin = UserFactory( is_staff=True, ) client = Client() client.force_login(admin) return client
class ActionAdminTests(TestCase): def setUp(self): # We'll need a report and a handful of actions self.client = Client() self.superuser = User.objects.create_superuser('ACTION_EXPORT_TEST_USER', '*****@*****.**', '') self.report = Report.objects.create(**SAMPLE_REPORT) self.url = reverse('admin:actstream_action_changelist') [add_activity(self.superuser, 'verb', 'description', self.report) for _ in range(5)] def test_action_csv_export(self): """ Selecting Actions and triggering the `export_actions_as_csv` action returns a StreamingHttpResponse containing a csv file with headers and all selected actions """ self.client.force_login(self.superuser) form_data = {'action': 'export_actions_as_csv', '_selected_action': [action.id for action in Action.objects.all()]} response = self.client.post(self.url, form_data) # Read through the entire streamed response rows = [r.decode('utf-8') for r in response.streaming_content] # Parse the response as a csv reader = csv.reader(rows) exported_action_csv = [row for row in reader] # Headers + 5 actions expected self.assertEquals(len(exported_action_csv), 6) # Headers match ACTION_FIELDS self.assertEquals(exported_action_csv[0], ACTION_FIELDS)
def test_tweets_api(self): vitor, osvaldo, bia, anon = Client(), Client(), Client(), Client() vitor.force_login(User.objects.get(username='******')) osvaldo.force_login(User.objects.get(username='******')) bia.force_login(User.objects.get(username='******')) self._follow(vitor, '@bia') self._follow(osvaldo, '@bia') self._follow(osvaldo, '@vitor') self._follow(vitor, '@osvaldo') self._unfollow(vitor, '@osvaldo') self._tweet(bia, 'Penso, logo existo!') self._tweet(vitor, 'oi') self._tweet(vitor, 'tudo bom?') self._tweet(osvaldo, 'E=mc2') self._tweet(osvaldo, 'xau') self._assert_tweets_home(bia, ['Penso, logo existo!']) self._assert_tweets_home(vitor, ['tudo bom?', 'oi', 'Penso, logo existo!']) self._assert_tweets_home( osvaldo, ['xau', 'E=mc2', 'tudo bom?', 'oi', 'Penso, logo existo!']) self._assert_tweets_home( anon, ['xau', 'E=mc2', 'tudo bom?', 'oi', 'Penso, logo existo!']) self._assert_tweets_user(anon, '@osvaldo', ['xau', 'E=mc2']) self._assert_tweets_user(vitor, '@osvaldo', ['xau', 'E=mc2'])
class AdminSiteTests(TestCase): def setUp(self): self.client = Client() self.admin_user = get_user_model().objects.create_superuser( email='*****@*****.**', password='******') self.client.force_login(self.admin_user) self.user = get_user_model().objects.create_user( email='*****@*****.**', password='******', name='Test user nombre completo') def test_users_listed(self): """ testeart a los usuarios ha sido añadiso en la pagina usuario """ url = reverse('admin:core_user_changelist') res = self.client.get(url) self.assertContains(res, self.user.name) self.assertContains(res, self.user.email) def test_user_change_page(self): """ prueba que la pagina editada por el usuario funciona """ url = reverse('admin:core_user_change', args=[self.user.id]) res = self.client.get(url) self.assertEqual(res.status_code, 200)
class AuditLogMiddlewareTestCase(TestCase): def setUp(self): self.client = Client() User = get_user_model() self.user = User.objects.create_user(username="******", password="******") self.client.force_login(self.user) def test_audit_log_middleware_adds_username(self): """Test that X-Username is added for authenticated users.""" with self.modify_settings( MIDDLEWARE={"append": "common.middleware.AuditLogMiddleware"}): response = self.client.get("/") self.assertTrue(response.has_header("X-Username")) self.assertEqual(response["X-Username"], self.user.username) def test_audit_log_middleware_unauthenticated(self): """Test absence of X-Username header for unauthenticated users. First we logout the authenticated user, and then we check for the presence of X-Username in the response for a new request by an unauthenticated user. """ with self.modify_settings( MIDDLEWARE={"append": "common.middleware.AuditLogMiddleware"}): self.client.logout() response = self.client.get(settings.LOGIN_URL) self.assertFalse(response.has_header("X-Username"))
def admin_client(db, admin_user): """A Django test client logged in as an admin user.""" from django.test.client import Client client = Client() client.force_login(admin_user) return client
def pre_cache(**kwargs): from django.contrib.auth.models import User from django.core.cache import cache from django.core.cache.utils import make_template_fragment_key from django.test.client import Client from dashboard.models import DashboardPreset, Widget c = Client(HTTP_USER_AGENT='Mozilla/5.0') user = User.objects.filter(is_superuser=True).first() c.force_login(user) calculated_widgets = set() for dashboard in DashboardPreset.objects.all(): print("!!!", "Calc Dashboard ID =", dashboard.id) widgets_ids = set([w.id for w in dashboard.widgets.all()]) updated_widget_ids = widgets_ids - calculated_widgets calculated_widgets = calculated_widgets.union(widgets_ids) for widget_id in updated_widget_ids: print("Widget id =", widget_id) key = make_template_fragment_key("widget", [widget_id]) cache.delete(key) try: c.get(f'/dashboard/{dashboard.id}/') except Exception as e: print("!!!", "Exception") try: print("!!!", e) except: pass else: print("!!! Success")
def test_tweets_api(self): newton, einstein, descartes, anon = Client(), Client(), Client( ), Client() newton.force_login(User.objects.get(username='******')) einstein.force_login(User.objects.get(username='******')) descartes.force_login(User.objects.get(username='******')) self._follow(newton, '@descartes') self._follow(einstein, '@descartes') self._follow(einstein, '@newton') self._follow(newton, '@einstein') self._unfollow(newton, '@einstein') self._tweet(descartes, PENSOLOGO) self._tweet(newton, PRIMEIRALEI) self._tweet(newton, GRAVITACAO) self._tweet(einstein, 'E = mc2') self._tweet(einstein, INSANIDADE) self._assert_tweets_home(descartes, [PENSOLOGO]) self._assert_tweets_home(newton, [GRAVITACAO, PRIMEIRALEI, PENSOLOGO]) self._assert_tweets_home( einstein, [INSANIDADE, 'E = mc2', GRAVITACAO, PRIMEIRALEI, PENSOLOGO]) self._assert_tweets_home( anon, [INSANIDADE, 'E = mc2', GRAVITACAO, PRIMEIRALEI, PENSOLOGO]) self._assert_tweets_user(anon, '@einstein', [INSANIDADE, 'E = mc2']) self._assert_tweets_user(newton, '@einstein', [INSANIDADE, 'E = mc2'])
class TestContentReplyView(TestCase): @classmethod def setUpTestData(cls): super().setUpTestData() user = UserFactory() cls.content = ContentFactory(author=user.profile) def setUp(self): super().setUp() self.client = Client() def test_view_renders(self): self.client.force_login(self.content.author.user) response = self.client.get(reverse("content:reply", kwargs={"pk": self.content.id})) self.assertEqual(response.status_code, 200) def test_redirects_to_login_if_not_logged_in(self): response = self.client.get(reverse("content:reply", kwargs={"pk": self.content.id})) self.assertEqual(response.status_code, 302) def test_form_valid(self): self.client.force_login(self.content.author.user) response = self.client.post( reverse("content:reply", kwargs={"pk": self.content.id}), {"text": "foobar", "visibility": 0, "pinned": False} ) self.assertEqual(response.status_code, 302) self.content.refresh_from_db() self.assertEqual(self.content.children.count(), 1)
def test_should_not_create_status(self): client = Client() user = create_user(is_staff=False) client.force_login(user) response = client.post(reverse(urls.STATUS_CREATE), STATUS_DATA) self.assertEqual(response.status_code, 302) self.assertEqual(len(TaskStatus.objects.all()), 0)
class TestUserDeleteView(BaseUserTestCase): def setUp(self): """ This method will run before any test. """ super(TestUserDeleteView, self).setUp() self.url = reverse_lazy('users:delete') self.client = Client() def tearDownUser(self): """ This method will run after any test. """ self.user.delete() def test_delete_user_ok(self): """ Test is user is being correcty deleted. """ self.assertEquals(User.objects.count(), 1) self.client.force_login(user=self.user) response = self.client.post(self.url, follow=True) home_url = reverse_lazy('core:home') self.assertRedirects(response, home_url) self.assertEquals(User.objects.count(), 0)
def get_headers(name): user = User.objects.create_user(username=name) client = Client() client.force_login(user) scn = settings.SESSION_COOKIE_NAME return [(b'cookie', '{}={}'.format(scn, client.cookies[scn].value).encode())]
def client(): """Fixture to provide Django test client.""" user = UserFactory(is_superuser=True) client = Client() client.force_login(user=user, backend='django.contrib.auth.backends.ModelBackend') return client
def test_tweets_api(self): newton, eistein, descartes, annonymous = Client(), Client(), Client( ), Client() newton.force_login(User.objects.get(username='******')) eistein.force_login(User.objects.get(username='******')) descartes.force_login(User.objects.get(username='******')) self._follow(newton, '@descartes') self._follow(eistein, '@descartes') self._follow(eistein, '@newton') self._follow(newton, '@einstein') self._unfollow(newton, '@einstein') self._tweet(descartes, DESCARTE_TWEET_1) self._tweet(newton, NEWTON_FIRST_LAW_TWEET) self._tweet(newton, NEWTON_SECOND_LAW_TWEET) self._tweet(eistein, 'E = MC2') self._tweet(eistein, 'Potato') self._assert_home_tweets(descartes, [DESCARTE_TWEET_1]) self._assert_home_tweets(newton, [ NEWTON_SECOND_LAW_TWEET, NEWTON_FIRST_LAW_TWEET, DESCARTE_TWEET_1 ]) self._assert_home_tweets(eistein, [ 'Potato', 'E = MC2', NEWTON_SECOND_LAW_TWEET, NEWTON_FIRST_LAW_TWEET, DESCARTE_TWEET_1 ]) self._assert_home_tweets(annonymous, [ 'Potato', 'E = MC2', NEWTON_SECOND_LAW_TWEET, NEWTON_FIRST_LAW_TWEET, DESCARTE_TWEET_1 ]) self._assert_tweets_user(annonymous, '@einstein', ['Potato', 'E = MC2']) self._assert_tweets_user(newton, '@einstein', ['Potato', 'E = MC2'])
class UsagersDetailsPageTests(TestCase): def setUp(self): self.client = Client() self.aidant = AidantFactory() self.usager = UsagerFactory() self.mandat = MandatFactory(organisation=self.aidant.organisation, usager=self.usager) AutorisationFactory(mandat=self.mandat) def test_usager_details_url_triggers_the_usager_details_view(self): found = resolve(f"/usagers/{self.usager.id}/") self.assertEqual(found.func, usagers.usager_details) def test_usager_details_url_triggers_the_usager_details_template(self): self.client.force_login(self.aidant) response = self.client.get(f"/usagers/{self.usager.id}/") self.assertTemplateUsed(response, "aidants_connect_web/usager_details.html") def test_usager_details_template_dynamic_title(self): self.client.force_login(self.aidant) response = self.client.get(f"/usagers/{self.usager.id}/") response_content = response.content.decode("utf-8") self.assertIn("<title>Aidants Connect - Homer Simpson</title>", response_content)
class TestViewEmployee(TestCase): """ Test if View Employee is working correctly """ def setUp(self): """ This method will run before any test. """ self.client = Client() self.user = self.make_user() self.employee = Employee.objects.create( cpf="974.220.200-16", user=self.user, departament=Employee.ADMINISTRATION) def test_employee_get_context_data(self): """ Makes sure that the employee data is showing at the user detail view """ self.employee.save() self.client.force_login(user=self.user) response = self.client.get(path='/users/testuser/', follow=True) self.assertEquals(response.status_code, 200) self.assertEquals(self.user.employee.cpf, self.employee.cpf) self.assertContains(response, text=self.user.username) self.assertContains(response, text=self.user.username) self.assertContains(response, text=self.user.employee.cpf)
def user_client(db, user): """A Django test client logged in as an user.""" from django.test.client import Client client = Client() client.force_login(user) return client
class GlobalSettingsViewAuthenticated(TestCase): """Tests for authenticated users""" def setUp(self): self.user = get_user_model().objects.create_user( "*****@*****.**", "django123") self.settings_obj = GlobalInfo.objects.first() self.client = Client() self.client.force_login(self.user) def tearDown(self): self.settings_obj.logo.delete() def test_page_loads_successfully(self): res = self.client.get(SETTINGS_URL) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, "users/global.html") def test_uploading_logo_successfull(self): with tempfile.NamedTemporaryFile(suffix=".jpg") as temp_logo: image = Image.new("RGB", (10, 10)) image.save(temp_logo, format="JPEG") temp_logo.seek(0) res = self.client.post(SETTINGS_URL, {"logo": temp_logo}, format="multipart/form-data") self.settings_obj.refresh_from_db() self.assertEqual(res.status_code, 302) self.assertTrue(os.path.exists(self.settings_obj.logo.path))
def test_setting_csv_hotel_success(self): """ Tests the import from remote file for hotels works fine """ from django.contrib.messages import get_messages path = reverse("setting-csv") user = mixer.blend(User, is_staff=True, is_superuser=True) client = Client() client.force_login(user) client.post( path, { "title": "city", "url": "http://rachel.maykinmedia.nl/djangocase/city.csv", "username": "******", "password": "******", "save": "on" }) r = client.post( path, { "title": "hotel", "url": "http://rachel.maykinmedia.nl/djangocase/hotel.csv", "username": "******", "password": "******", "save": "on" }) messages = list(get_messages(r.wsgi_request)) assert r.status_code == 200 assert len(messages) == 1 assert str(messages[0]) == "Successfully Uploaded!"
class TestCreateUpdateCredentials(TestCase): @classmethod def setUpTestData(cls): cls.user = users.create_user() cls.credential_whatsapp = baker.make(Credential, name='Whatsapp', owner=cls.user) def setUp(self): self.client = Client() self.client.force_login(self.user) def test_create_credential(self): expected_credential = { 'name': 'Facebook', 'username': '******', 'password': '******', 'link': 'https://facebook.com' } response = self.client.post('/api/credentials/save', expected_credential) self.assertEqual(response.status_code, 200) credential = Credential.objects.get( username=expected_credential['username']) credential_dict = credential.to_dict_json() self.assertEqual(credential_dict['name'], expected_credential['name']) self.assertEqual(credential_dict['username'], expected_credential['username']) self.assertIn('created_at', credential_dict) self.assertIn('last_updated', credential_dict) self.assertIn('last_accessed', credential_dict) log = ActivityLog.objects.filter(type=CREDENTIAL_CREATION, credential=credential) self.assertTrue(log.exists()) self.assertEqual(log.count(), 1) def test_save_credential(self): expected_credential = self.credential_whatsapp.to_dict_json() expected_credential.update({'name': 'Whatsapp 2'}) response = self.client.post('/api/credentials/save', expected_credential) self.assertEqual(response.status_code, 200) credential = Credential.objects.get(pk=self.credential_whatsapp.pk) self.assertEqual(credential.name, expected_credential['name']) log = ActivityLog.objects.filter(type=CREDENTIAL_EDITING, credential=credential) self.assertTrue(log.exists()) self.assertEqual(log.count(), 1) def test_delete_credential(self): response = self.client.post('/api/credentials/delete', {'id': self.credential_whatsapp.pk}) self.assertEqual(response.status_code, 200) credential = Credential.objects.filter(pk=self.credential_whatsapp.pk, active=True) self.assertFalse(credential.exists()) log = ActivityLog.objects.filter(type=CREDENTIAL_DELETE) self.assertTrue(log.exists()) self.assertEqual(log.count(), 1)
class TrackingTestCase(TestCase, SubscriptionTestMixin): def setUp(self): self.client = Client() def test_tracking(self): response = self.client.get("/", follow=True) self.assertEqual(response.status_code, 200) self.assertTrue("UA-58468401-4" in response.content) def test_start_authorized(self): user = UserGenerator().generate() is_loggedin = self.client.login( username=user.username, password=DEFAULT_TEST_DATA['password']) self.assertTrue(is_loggedin) response = self.client.get(reverse('start'), follow=True) self.assertEqual(response.status_code, 200) self.assertTrue("UA-58468401-4" in response.content) self.assertTrue("Willkommen" in response.content) self.assertTrue("shareholder_list" in response.content) # self.assertTrue('download/pdf' in response.content) # self.assertTrue('download/csv' in response.content) def test_start_authorized_with_operator(self): user = UserGenerator().generate() is_operator_added = _add_company_to_user_via_rest(user) self.assertTrue(is_operator_added) self.client.force_login(user) self.add_subscription(user.operator_set.first().company) response = self.client.get(reverse('start'), follow=True) self.assertEqual(response.status_code, 200) self.assertTrue("Willkommen" in response.content) self.assertTrue("shareholder_list" in response.content) def test_start_nonauthorized(self): user = UserGenerator().generate() is_loggedin = self.client.login( username=user.username, password='******') self.assertFalse(is_loggedin) response = self.client.get(reverse('start'), follow=True) self.assertEqual(response.status_code, 200) # redirect to login self.assertIn(_('Register'), response.content.decode('utf-8'))
def test_create_tag(self): client = Client() user = create_user(is_staff=False) client.force_login(user) response = client.post(reverse(urls.TAG_CREATE), TAG_DATA) tag_in_db = Tag.objects.get(name=TAG_NAME) self.assertEqual(response.status_code, 302) self.assertEqual(TAG_NAME, tag_in_db.name)
def test_view_passes_form_in_context(self): """Ensure the view passes the correct Form in the context""" c = Client() c.force_login(self.user) response = c.get(reverse(self.test_url_name), user=self.user) self.assertEqual(WftdaStatBookForm, type(response.context['form']))
def test_create_status(self): client = Client() user = create_user(is_staff=True) client.force_login(user) response = client.post(reverse(urls.STATUS_CREATE), STATUS_DATA) status_in_db = TaskStatus.objects.get(name=STATUS_NAME) self.assertEqual(response.status_code, 302) self.assertEqual(STATUS_NAME, status_in_db.name)
def test_auth_api(self): client = Client() client.force_login(User.objects.get(username='******')) client.post('/api/posts', fixtures.get_post()) r2 = client.post('/api/comments', fixtures.get_comment()) self.assertEqual(1, r2.json()['id'])
def admin_client(): admin = UserFactory( is_staff=True, person=None, ) client = Client() client.force_login(admin) return client
def test_create_view_response_when_user_is_admin(admin_user): client = Client() client.force_login(admin_user) response = client.get(reverse('users:create')) assert response.status_code == 200 assertTemplateUsed(response, "users/create.html") assertTemplateUsed(response, "users/_form.html")
class DeauthorizedTest(TestCase): def setUp(self): self.factory = RequestFactory() self.client = Client() def test_index_view(self): request = self.factory.get('/') response = index(request) assert response.status_code == 200 def test_auth_view(self): request = self.factory.get('/auth') response = auth(request) assert response.status_code == 302 def test_logout_view(self): user_params = dict(id_token=MOCK_ID_TOKEN, access_token=MOCK_ACCESS_TOKEN) user, created = User.objects.get_or_create(**user_params) user.set_unusable_password() user.save() self.client.force_login(user) logout_response = self.client.get('/logout') assert logout_response.status_code == 302 assert MOCK_ID_TOKEN in logout_response.url @mock.patch('requests.get', side_effect=mocked_requests_get) @mock.patch('requests.post', side_effect=mocked_requests_post) def test_auth_callback_view(self, mock_post, mock_get): request_params = {'code': 'test', 'state': 'test'} response = self.client.get('/openid_auth_callback', request_params) assert response.status_code == 200 assert 'text/html' in response.get('content-type') user = User.objects.get(id_token=MOCK_ID_TOKEN) assert user is not None assert user.id_token == MOCK_ID_TOKEN assert user.access_token == MOCK_ACCESS_TOKEN @mock.patch('requests.get', side_effect=mocked_requests_get) @mock.patch('requests.post', side_effect=mocked_requests_post) def test_auth_callback_creates_user(self, mock_post, mock_get): request_params = {'code': 'test', 'state': 'test'} response = self.client.get('/openid_auth_callback', request_params) assert response.status_code == 200 assert 'text/html' in response.get('content-type') user = User.objects.get(id_token=MOCK_ID_TOKEN) assert user is not None assert user.id_token == MOCK_ID_TOKEN assert user.access_token == MOCK_ACCESS_TOKEN def test_user_get_or_create(self): token = 'asdf' user, _ = User.objects.get_or_create(id_token='asdf') assert user is not None assert user.id_token == token assert user.access_token is None
class EstudiosTest(TestCase): def setUp(self): self.config = mommy.make(Configuracion, id=000) self.config.save() self.user = User.objects.create_user(username='******', password='******') self.factory = RequestFactory() self.usprfl = UserProfile(user=self.user, tipoUsr=1, id_estudioc=1) self.usprfl.save() self.client = Client() self.client.force_login(self.user) self.request = self.factory.get('/') self.request.user = self.user self.estudio = mommy.make(DriEstudio, id_estudioc=1, numero='1', denominacion='Estudio PEPE', usuario='qwerty', clave='qwerty', email='*****@*****.**') un_tributo = mommy.make(Tributo, id_tributo=6, descripcion='DReI', abreviatura='DRI') self.padrones_estudio = mommy.make(DriEstudioPadron, id_estudioc=self.estudio, id_padron=1) self.cuotas = mommy.make(Cuotas, tributo=un_tributo, id_padron=1, id_responsable=2, _quantity=3) def test_EstudiosView(self): response = self.client.get(reverse('padrones_estudio')) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'padrones_estudio.html') context = response.context self.assertNotEqual(context['estudio'], None) self.assertNotEqual(context['padr'], None) self.assertNotEqual(context['padron'], None) response2 = self.client.get(reverse('padrones_responsable')) self.assertEqual(response2.status_code, 302) def test_EstudiosUpdateView(self): response = self.client.get(reverse('estudio_editar', kwargs={'pk': 1})) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'estudio_update.html') context = response.context self.assertNotEqual(context['sitio'], None) response2 = self.client.get(reverse('estudio_editar', kwargs={'pk': 2})) self.assertEqual(response2.status_code, 302)
def outreach_client(outreach_user): ''' Returns a Django test client with a logged-in Outreach Coordinator. ''' client = DjangoClient() client.force_login(outreach_user) return client
def test_logout(self): client = Client() customer = self.get_customer_account() client.force_login(customer) response = client.get(reverse('index'), follow=True) self.assertEqual(len(response.redirect_chain), 1) self.assertEqual('/', reverse('index')) client.get(reverse('accounts:account-logout'), follow=True) response = client.get(reverse('index'), follow=True) self.assertEqual(len(response.redirect_chain), 2) self.assertTrue(settings.LOGIN_URL in response.redirect_chain[1][0])
class ApiEndpointsTests(TestCase): def setUp(self): self.user = User.objects.create_superuser(username='******', password='******', email='*****@*****.**') self.user.save() self.c = Client() self.c.force_login(self.user) def test_basic_api(self): response = self.c.get("") self.assertEqual(response.status_code, 200) def test_get_empty_volunteers(self): response = self.c.get("/api/volunteers/") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['count'], 0) self.assertEqual(response.json()['results'], []) def test_get_empty_assignments(self): response = self.c.get("/api/assignments/") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['count'], 0) self.assertEqual(response.json()['results'], []) def test_admin(self): response = self.c.get("/admin/") self.assertEqual(response.status_code, 200) def create_contact(self): return Contact.objects.create(email="*****@*****.**", preferred_contact=1) def create_volunteer(self): return Volunteer.objects.create(first_name="John", last_name="Doe", sex=1, volunteer_level=1, created_at=timezone.now(), contact=self.create_contact()) def test_volunteer(self): con = self.create_contact() vol = self.create_volunteer() self.assertTrue(isinstance(con, Contact)) self.assertEqual(con.email, "*****@*****.**") self.assertTrue(isinstance(vol, Volunteer)) self.assertEqual(vol.first_name, "John") self.assertEqual(vol.last_name, "Doe") self.assertEqual(vol.sex, 1) def test_contact(self): con = self.create_contact() self.assertTrue(isinstance(con, Contact)) self.assertEqual(con.preferred_contact, 1) self.assertEqual(con.email, "*****@*****.**") def test_post(self): response = self.c.post("/api/volunteers/", "volunteer_jean object") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['count'], 1) def test_delete(self): response1 = self.c.post("/api/volunteers/", "add a volunteer object") response2 = self.c.post("/api/volunteers/", "delete a volunteer objects") self.assertEqual(response1.status_code, 200) self.assertEqual(response2.status_code, 200) self.assertEqual(response1.json()['count'], response2.json()['count']+1) def test_update_volunteers(self): response = self.c.post("/api/volunteers/", "data-for-updating-a-volunteer") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['whatever_field'], "updated value") def test_purgeList(self): new_array = {'id':[1,2,3]} old_array = [{'id': 3}, {'id':2}, {'id':1}] purgeList(self, old_array, new_array) print(old_array) print(new_array) self.assertTrue(False)
class SkeletonSummaryTableTests(TransactionTestCase): """Test the trigger based skeleton summary upate. """ def setUp(self): """Create a project and a suer with browse/annotate permissions. """ self.client = Client() admin = User.objects.create(username="******", password="******", is_superuser=True) project = Project.objects.create(title="Testproject") self.project_id = project.id # Set project up for tracing tracing.setup_tracing(self.project_id, admin) self.authenticate() def authenticate(self): self.client.force_login(User.objects.get_or_create(username='******')[0]) user = User.objects.get(username="******") project = Project.objects.get(pk=self.project_id) assign_perm('can_browse', user, project) assign_perm('can_annotate', user, project) def get_summary(self, cursor, skeleton_id): cursor.execute(""" SELECT skeleton_id, cable_length, num_nodes FROM catmaid_skeleton_summary WHERE skeleton_id = %(skeleton_id)s """, { 'skeleton_id': skeleton_id }) summaries = list(map(lambda x: { 'skeleton_id': x[0], 'cable_length': x[1], 'num_nodes': x[2] }, cursor.fetchall())) if summaries and len(summaries) > 0: return summaries[0] else: return None def test_create_update_delete_skeleton(self): """Test summary before and after creating a new neuron. """ self.authenticate() cursor = connection.cursor() # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 1, 'y': 2, 'z': 3, 'confidence': 5, 'parent_id': -1, 'radius': 2 }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) skeleton_id = parsed_response['skeleton_id'] # Expect basic summary setup initial_skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(initial_skeleton_summary, None) self.assertEqual(initial_skeleton_summary['cable_length'], 0.0) self.assertEqual(initial_skeleton_summary['num_nodes'], 1) # Add second node response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 4, 'y': 5, 'z': 6, 'confidence': 5, 'parent_id': parsed_response['treenode_id'], 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 5.1961524) self.assertEqual(skeleton_summary['num_nodes'], 2) # Remember second node second_node_id = parsed_response['treenode_id'] # Add third node response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 7, 'y': 8, 'z': 9, 'confidence': 5, 'parent_id': second_node_id, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Remember third node third_node_id = parsed_response['treenode_id'] # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.3923048) self.assertEqual(skeleton_summary['num_nodes'], 3) # Move second node response = self.client.post( '/%d/node/update' % self.project_id, { 'state': make_nocheck_state(), 't[0][0]': second_node_id, 't[0][1]': 10, 't[0][2]': 11, 't[0][3]': 12}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.7846096908265) self.assertEqual(skeleton_summary['num_nodes'], 3) # Delete last node response = self.client.post( '/%d/treenode/delete' % self.project_id, { 'state': make_nocheck_state(), 'treenode_id': third_node_id }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 15.588457268119) self.assertEqual(skeleton_summary['num_nodes'], 2) # Delete neuron response = self.client.post('/%d/neurons/from-models' % self.project_id, { 'model_ids[0]': skeleton_id }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) neuron_id = parsed_response[str(skeleton_id)] response = self.client.post( '/{}/neuron/{}/delete'.format(self.project_id, neuron_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect no summary entry for deleted skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIs(skeleton_summary, None) def create_partition(self, partition, root=None): ids = [] skeleton_id = None if root is None: root = -1 parent = root for pos in partition: # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': pos[0], 'y': pos[1], 'z': pos[2], 'confidence': 5, 'parent_id': parent, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) parent = parsed_response['treenode_id'] ids.append(parsed_response['treenode_id']) if not skeleton_id: skeleton_id = parsed_response['skeleton_id'] return ids, skeleton_id def test_branches_and_split(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1,2,3), (4,5,6), (7,8,9), (10,11,12), (13,14,15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2,6,2), (6,2,1), (4,6,1)] branch_a_ids, _ = self.create_partition(branch_a, main_trunk_ids[1]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Branch B branch_b = [(17,12,2), (42,21,12), (52,61,-1)] branch_b_ids, _ = self.create_partition(branch_b, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 119.453404476) self.assertEqual(skeleton_summary['num_nodes'], 11) # Branch C branch_c = [(10,-12,23), (-4,11,122), (5,12,-11)] branch_c_ids, _ = self.create_partition(branch_c, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 380.85271251741471) self.assertEqual(skeleton_summary['num_nodes'], 14) # Split response = self.client.post('/%d/skeleton/split' % self.project_id, { 'treenode_id': main_trunk_ids[3], 'upstream_annotation_map': '{}', 'downstream_annotation_map': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['existing_skeleton_id'], skeleton_id) new_skeleton_id = parsed_response['new_skeleton_id'] # Old skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 25.1915791414) self.assertEqual(skeleton_summary['num_nodes'], 6) # New skeleton is bigger one by default skeleton_summary = self.get_summary(cursor, new_skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 350.46498095330807811942) self.assertEqual(skeleton_summary['num_nodes'], 8) def test_merge(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1,2,3), (4,5,6), (7,8,9), (10,11,12), (13,14,15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2,6,2), (6,2,1), (4,6,1)] branch_a_ids, skeleton_id_a = self.create_partition(branch_a) skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.216698601) self.assertEqual(skeleton_summary['num_nodes'], 3) # Merge A into main branch response = self.client.post('/%d/skeleton/join' % self.project_id, { 'from_id': main_trunk_ids[1], 'to_id': branch_a_ids[0], 'annotation_set': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['result_skeleton_id'], skeleton_id) self.assertEqual(parsed_response['deleted_skeleton_id'], skeleton_id_a) # Check summary of kept skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Check summary of removed skeleton skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIs(skeleton_summary, None) def test_recreation_in_sql(self): """Test whether a recreation from scratch of the summary table works as expected. """ self.authenticate() # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 1, 'y': 2, 'z': 3, 'confidence': 5, 'parent_id': -1, 'radius': 2 }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) skeleton_id = parsed_response['skeleton_id'] cursor = connection.cursor() cursor.execute(""" SELECT refresh_skeleton_summary_table(); """) # Expect basic summary setup initial_skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(initial_skeleton_summary, None) self.assertEqual(initial_skeleton_summary['cable_length'], 0.0) self.assertEqual(initial_skeleton_summary['num_nodes'], 1)
class TestSurveyAdminViews(TestCase, MoloTestCaseMixin): def setUp(self): self.client = Client() self.mk_main() self.main = Main.objects.all().first() self.language_setting = Languages.objects.create( site_id=self.main.get_site().pk) self.english = SiteLanguageRelation.objects.create( language_setting=self.language_setting, locale='en', is_active=True) self.french = SiteLanguageRelation.objects.create( language_setting=self.language_setting, locale='fr', is_active=True) self.section = self.mk_section(self.section_index, title='section') self.article = self.mk_article(self.section, title='article') # Create surveys index pages self.surveys_index = SurveysIndexPage.objects.child_of( self.main).first() self.user = User.objects.create_user( username='******', email='*****@*****.**', password='******') self.super_user = User.objects.create_superuser( username='******', password='******', email='*****@*****.**') def create_molo_survey_page(self, parent, **kwargs): molo_survey_page = MoloSurveyPage( title='Test Survey', slug='test-survey', introduction='Introduction to Test Survey ...', thank_you_text='Thank you for taking the Test Survey', **kwargs ) parent.add_child(instance=molo_survey_page) molo_survey_page.save_revision().publish() molo_survey_form_field = MoloSurveyFormField.objects.create( page=molo_survey_page, sort_order=1, label='Your favourite animal', admin_label='fav_animal', field_type='singleline', required=True ) return molo_survey_page, molo_survey_form_field def create_personalisable_molo_survey_page(self, parent, **kwargs): # create segment for personalisation test_segment = Segment.objects.create(name="Test Segment") UserIsLoggedInRule.objects.create( segment=test_segment, is_logged_in=True) personalisable_survey = PersonalisableSurvey( title='Test Survey', slug='test-survey', introduction='Introduction to Test Survey ...', thank_you_text='Thank you for taking the Test Survey', **kwargs ) parent.add_child(instance=personalisable_survey) personalisable_survey.save_revision().publish() molo_survey_form_field = PersonalisableSurveyFormField.objects.create( field_type='singleline', label='Question 1', admin_label='question_1', page=personalisable_survey, segment=test_segment) return personalisable_survey, molo_survey_form_field def test_survey_create_invalid_with_duplicate_questions(self): self.client.force_login(self.super_user) response = self.client.get( '/admin/pages/add/surveys/molosurveypage/%d/' % self.surveys_index.pk) self.assertEqual(response.status_code, 200) form = response.context['form'] data = form.initial data.update( form.formsets['survey_form_fields'].management_form.initial) data.update({u'description-count': 0}) data.update({ 'survey_form_fields-0-admin_label': 'a', 'survey_form_fields-0-label': 'question 1', 'survey_form_fields-0-default_value': 'a', 'survey_form_fields-0-field_type': 'radio', 'survey_form_fields-0-help_text': 'b', 'survey_form_fields-1-admin_label': 'b', 'survey_form_fields-1-label': 'question 1', 'survey_form_fields-1-default_value': 'a', 'survey_form_fields-1-field_type': 'radio', 'survey_form_fields-1-help_text': 'b', 'go_live_at': '', 'expire_at': '', 'image': '', 'survey_form_fields-0-ORDER': 1, 'survey_form_fields-0-required': 'on', 'survey_form_fields-0-skip_logic-0-deleted': '', 'survey_form_fields-0-skip_logic-0-id': 'None', 'survey_form_fields-0-skip_logic-0-order': 0, 'survey_form_fields-0-skip_logic-0-type': 'skip_logic', 'survey_form_fields-0-skip_logic-0-value-choice': 'a', 'survey_form_fields-0-skip_logic-0-value-question_0': 'a', 'survey_form_fields-0-skip_logic-0-value-skip_logic': 'next', 'survey_form_fields-0-skip_logic-0-value-survey': '', 'survey_form_fields-0-skip_logic-count': 1, 'survey_form_fields-1-ORDER': 2, 'survey_form_fields-1-required': 'on', 'survey_form_fields-1-skip_logic-0-deleted': '', 'survey_form_fields-1-skip_logic-0-id': 'None', 'survey_form_fields-1-skip_logic-0-order': 0, 'survey_form_fields-1-skip_logic-0-type': 'skip_logic', 'survey_form_fields-1-skip_logic-0-value-choice': 'a', 'survey_form_fields-1-skip_logic-0-value-question_0': 'a', 'survey_form_fields-1-skip_logic-0-value-skip_logic': 'next', 'survey_form_fields-1-skip_logic-0-value-survey': '', 'survey_form_fields-1-skip_logic-count': 1, 'survey_form_fields-INITIAL_FORMS': 0, 'survey_form_fields-MAX_NUM_FORMS': 1000, 'survey_form_fields-MIN_NUM_FORMS': 0, 'survey_form_fields-TOTAL_FORMS': 2, 'terms_and_conditions-INITIAL_FORMS': 0, 'terms_and_conditions-MAX_NUM_FORMS': 1000, 'terms_and_conditions-MIN_NUM_FORMS': 0, 'terms_and_conditions-TOTAL_FORMS': 0, }) response = self.client.post( '/admin/pages/add/surveys/molosurveypage/%d/' % self.surveys_index.pk, data=data) self.assertEqual(response.status_code, 200) form = response.context['form'].formsets['survey_form_fields'] err = u'This question appears elsewhere in the survey. ' \ u'Please rephrase one of the questions.' self.assertTrue(err in form.errors[1]['label']) def test_survey_edit_view(self): self.client.force_login(self.super_user) child_of_index_page = create_molo_survey_page( self.surveys_index, title="Child of SurveysIndexPage Survey", slug="child-of-surveysindexpage-survey" ) form_field = MoloSurveyFormField.objects.create( page=child_of_index_page, field_type='radio', choices='a,b,c') response = self.client.get( '/admin/pages/%d/edit/' % child_of_index_page.pk) self.assertEqual(response.status_code, 200) form = response.context['form'] data = form.initial data.update( form.formsets['survey_form_fields'].management_form.initial) data.update({u'description-count': 0}) data.update({ 'survey_form_fields-0-admin_label': 'a', 'survey_form_fields-0-label': 'a', 'survey_form_fields-0-default_value': 'a', 'survey_form_fields-0-field_type': form_field.field_type, 'survey_form_fields-0-help_text': 'a', 'survey_form_fields-0-id': form_field.pk, 'go_live_at': '', 'expire_at': '', 'image': '', 'survey_form_fields-0-ORDER': 1, 'survey_form_fields-0-required': 'on', 'survey_form_fields-0-skip_logic-0-deleted': '', 'survey_form_fields-0-skip_logic-0-id': 'None', 'survey_form_fields-0-skip_logic-0-order': 0, 'survey_form_fields-0-skip_logic-0-type': 'skip_logic', 'survey_form_fields-0-skip_logic-0-value-choice': 'a', 'survey_form_fields-0-skip_logic-0-value-question_0': 'a', 'survey_form_fields-0-skip_logic-0-value-skip_logic': 'next', 'survey_form_fields-0-skip_logic-0-value-survey': '', 'survey_form_fields-0-skip_logic-count': 1, 'survey_form_fields-INITIAL_FORMS': 1, 'survey_form_fields-MAX_NUM_FORMS': 1000, 'survey_form_fields-MIN_NUM_FORMS': 0, 'survey_form_fields-TOTAL_FORMS': 1, 'terms_and_conditions-INITIAL_FORMS': 0, 'terms_and_conditions-MAX_NUM_FORMS': 1000, 'terms_and_conditions-MIN_NUM_FORMS': 0, 'terms_and_conditions-TOTAL_FORMS': 0, }) response = self.client.post( '/admin/pages/%d/edit/' % child_of_index_page.pk, data=data) self.assertEqual( response.context['message'], u"Page 'Child of SurveysIndexPage Survey' has been updated." ) data.update({ 'survey_form_fields-0-skip_logic-0-value-choice': 'a' + 'a' * CHARACTER_COUNT_CHOICE_LIMIT, }) response = self.client.post( '/admin/pages/%d/edit/' % child_of_index_page.pk, data=data) self.assertEqual(response.status_code, 200) form = response.context['form'].formsets['survey_form_fields'] err = u'The combined choices\' maximum characters ' \ u'limit has been exceeded ({max_limit} ' \ u'character(s)).' self.assertTrue( err.format(max_limit=CHARACTER_COUNT_CHOICE_LIMIT) in form.errors[0]['field_type'].error_list[0] ) def test_survey_edit_invalid_with_duplicate_questions(self): self.client.force_login(self.super_user) child_of_index_page = create_molo_survey_page( self.surveys_index, title="Child of SurveysIndexPage Survey", slug="child-of-surveysindexpage-survey" ) form_field_1 = MoloSurveyFormField.objects.create( page=child_of_index_page, label='question 1', field_type='radio', choices='a,b,c') form_field_2 = MoloSurveyFormField.objects.create( page=child_of_index_page, label='question 2', field_type='radio', choices='a,b,c') response = self.client.get( '/admin/pages/%d/edit/' % child_of_index_page.pk) self.assertEqual(response.status_code, 200) form = response.context['form'] data = form.initial data.update( form.formsets['survey_form_fields'].management_form.initial) data.update({u'description-count': 0}) data.update({ 'survey_form_fields-0-admin_label': 'a', 'survey_form_fields-0-label': form_field_1.label, 'survey_form_fields-0-default_value': 'a', 'survey_form_fields-0-field_type': form_field_1.field_type, 'survey_form_fields-0-help_text': 'a', 'survey_form_fields-0-id': form_field_1.pk, 'survey_form_fields-1-admin_label': 'a', 'survey_form_fields-1-label': form_field_1.label, 'survey_form_fields-1-default_value': 'a', 'survey_form_fields-1-field_type': form_field_2.field_type, 'survey_form_fields-1-help_text': 'a', 'survey_form_fields-1-id': form_field_2.pk, 'go_live_at': '', 'expire_at': '', 'image': '', 'survey_form_fields-0-ORDER': 1, 'survey_form_fields-0-required': 'on', 'survey_form_fields-0-skip_logic-0-deleted': '', 'survey_form_fields-0-skip_logic-0-id': 'None', 'survey_form_fields-0-skip_logic-0-order': 0, 'survey_form_fields-0-skip_logic-0-type': 'skip_logic', 'survey_form_fields-0-skip_logic-0-value-choice': 'a', 'survey_form_fields-0-skip_logic-0-value-question_0': 'a', 'survey_form_fields-0-skip_logic-0-value-skip_logic': 'next', 'survey_form_fields-0-skip_logic-0-value-survey': '', 'survey_form_fields-0-skip_logic-count': 1, 'survey_form_fields-1-ORDER': 2, 'survey_form_fields-1-required': 'on', 'survey_form_fields-1-skip_logic-0-deleted': '', 'survey_form_fields-1-skip_logic-0-id': 'None', 'survey_form_fields-1-skip_logic-0-order': 0, 'survey_form_fields-1-skip_logic-0-type': 'skip_logic', 'survey_form_fields-1-skip_logic-0-value-choice': 'a', 'survey_form_fields-1-skip_logic-0-value-question_0': 'a', 'survey_form_fields-1-skip_logic-0-value-skip_logic': 'next', 'survey_form_fields-1-skip_logic-0-value-survey': '', 'survey_form_fields-1-skip_logic-count': 1, 'survey_form_fields-INITIAL_FORMS': 2, 'survey_form_fields-MAX_NUM_FORMS': 1000, 'survey_form_fields-MIN_NUM_FORMS': 0, 'survey_form_fields-TOTAL_FORMS': 2, 'terms_and_conditions-INITIAL_FORMS': 0, 'terms_and_conditions-MAX_NUM_FORMS': 1000, 'terms_and_conditions-MIN_NUM_FORMS': 0, 'terms_and_conditions-TOTAL_FORMS': 0, }) response = self.client.post( '/admin/pages/%d/edit/' % child_of_index_page.pk, data=data) self.assertEqual(response.status_code, 200) form = response.context['form'].formsets['survey_form_fields'] err = u'This question appears elsewhere in the survey. ' \ u'Please rephrase one of the questions.' self.assertTrue(err in form.errors[1]['label']) def test_convert_to_article(self): molo_survey_page, molo_survey_form_field = \ self.create_molo_survey_page(parent=self.section_index) self.client.login(username='******', password='******') response = self.client.get(molo_survey_page.url) self.assertContains(response, molo_survey_page.title) self.assertContains(response, molo_survey_page.introduction) self.assertContains(response, molo_survey_form_field.label) response = self.client.post(molo_survey_page.url, { molo_survey_form_field.label.lower().replace(' ', '-'): 'python' }, follow=True) self.client.logout() self.client.login( username='******', password='******' ) # test shows convert to article button when no article created yet response = self.client.get( '/admin/surveys/submissions/%s/' % molo_survey_page.id) self.assertContains(response, 'Convert to Article') # convert submission to article SubmissionClass = molo_survey_page.get_submission_class() submission = SubmissionClass.objects.filter( page=molo_survey_page).first() response = self.client.get( '/surveys/submissions/%s/article/%s/' % ( molo_survey_page.id, submission.pk)) self.assertEquals(response.status_code, 302) article = ArticlePage.objects.last() submission = SubmissionClass.objects.filter( page=molo_survey_page).first() self.assertEquals(article.title, article.slug) self.assertEquals(submission.article_page, article) self.assertEqual( sorted([ body_elem['type'] for body_elem in article.body.stream_data]), ['paragraph', 'paragraph', 'paragraph'], ) self.assertEqual( sorted([ body_elem['value'] for body_elem in article.body.stream_data]), [str(submission.created_at), 'python', 'tester'], ) # first time it goes to the move page self.assertEquals( response['Location'], '/admin/pages/%d/move/' % article.id) # second time it should redirect to the edit page response = self.client.get( '/surveys/submissions/%s/article/%s/' % ( molo_survey_page.id, submission.pk)) self.assertEquals(response.status_code, 302) self.assertEquals( response['Location'], '/admin/pages/%d/edit/' % article.id) response = self.client.get( '/admin/surveys/submissions/%s/' % molo_survey_page.id) # it should not show convert to article as there is already article self.assertNotContains(response, 'Convert to Article') def test_export_submission_standard_survey(self): molo_survey_page, molo_survey_form_field = \ self.create_molo_survey_page(parent=self.section_index) self.client.force_login(self.user) answer = 'PYTHON' response = self.client.post(molo_survey_page.url, { molo_survey_form_field.label.lower().replace(' ', '-'): answer }) self.client.force_login(self.super_user) response = self.client.get( '/admin/surveys/submissions/%s/' % (molo_survey_page.id), {'action': 'CSV'}, ) self.assertEquals(response.status_code, 200) self.assertContains(response, 'Username') self.assertContains(response, 'Submission Date') self.assertNotContains(response, molo_survey_form_field.label) self.assertContains(response, molo_survey_form_field.admin_label) self.assertContains(response, answer) def test_export_submission_personalisable_survey(self): molo_survey_page, molo_survey_form_field = ( self.create_personalisable_molo_survey_page( parent=self.section_index)) answer = 'PYTHON' molo_survey_page.get_submission_class().objects.create( form_data=json.dumps({"question-1": answer}, cls=DjangoJSONEncoder), page=molo_survey_page, user=self.user ) self.client.force_login(self.super_user) response = self.client.get( '/admin/surveys/submissions/{}/'.format(molo_survey_page.id), {'action': 'CSV'}, ) self.assertEquals(response.status_code, 200) self.assertContains(response, 'Username') self.assertContains(response, 'Submission Date') self.assertNotContains(response, molo_survey_form_field.label) self.assertContains( response, '{} ({})'.format(molo_survey_form_field.admin_label, molo_survey_form_field.segment.name)) self.assertContains(response, self.user.username) self.assertContains(response, answer) def test_survey_index_view_displays_all_surveys(self): child_of_index_page = create_molo_survey_page( self.surveys_index, title="Child of SurveysIndexPage Survey", slug="child-of-surveysindexpage-survey" ) child_of_article_page = create_molo_survey_page( self.article, title="Child of Article Survey", slug="child-of-article-survey" ) self.client.force_login(self.super_user) response = self.client.get('/admin/surveys/') self.assertContains(response, child_of_index_page.title) self.assertContains(response, child_of_article_page.title) def test_segment_submission_rule_edit_shows_field_label(self): # create survey page molo_survey_page, molo_survey_form_field = ( self.create_personalisable_molo_survey_page( parent=self.section_index)) # create segment and rule test_segment = Segment.objects.create(name="Test Segment") rule = SurveySubmissionDataRule( segment=test_segment, survey=molo_survey_page, operator=SurveySubmissionDataRule.EQUALS, expected_response='super random text', field_name='question-1') rule.save() test_segment.save() self.client.force_login(self.super_user) response = self.client.get( '/admin/wagtail_personalisation/segment/edit/%d/' % test_segment.pk) self.assertNotContains(response, rule.field_name) self.assertContains(response, molo_survey_form_field.label)
def get_auth_client(username='******'): user = User.objects.create_user(username, 'pw') auth_client = Client() auth_client.force_login(user) return auth_client
class SGATestCase(TestCase): """ Parent test class for test cases """ def setUp(self): """ Common test setup """ super(SGATestCase, self).setUp() self.client = Client() self.user_model = get_user_model() self.default_course = self.get_test_course() def tearDown(self): shutil.rmtree(TEST_FILE_LOCATION, ignore_errors=True) ### # Helper functions ### def set_up_session_params(self, user, lti_params=None): """ Initializes session parameters (assumes test course) """ # Set up session # LTI params if lti_params: lti_params = lti_params else: lti_params = DEFAULT_LTI_PARAMS session = self.client.session session["LTI_LAUNCH"] = lti_params course = self.get_test_course() session["course_roles"] = {} session["course_roles"][str(course.id)] = get_role(user, course.id) session.save() def log_in_as(self, role, lti_params=None): """ Logs in as the role provided @param role: (str) role """ if role == Roles.student: self.log_in_as_student(lti_params=lti_params) elif role == Roles.grader: self.log_in_as_grader(lti_params=lti_params) elif role == Roles.admin: self.log_in_as_admin(lti_params=lti_params) else: # Assume anonymous, but logged in, user self.log_in_as_non_role_user(lti_params=lti_params) def log_in_as_admin(self, lti_params=None): """ Logs in as an admin in the test course """ admin_user = self.get_test_admin_user() self.client.force_login(admin_user) self.set_up_session_params(admin_user, lti_params=lti_params) def log_in_as_grader(self, lti_params=None): """ Logs in as a grader in the test course """ grader_user = self.get_test_grader_user() self.client.force_login(grader_user) self.set_up_session_params(grader_user, lti_params=lti_params) def log_in_as_student(self, lti_params=None): """ Logs in as a grader in the test course """ student_user = self.get_test_student_user() self.client.force_login(student_user) self.set_up_session_params(student_user, lti_params=lti_params) def log_in_as_non_role_user(self, lti_params=None): """ Logs in as user with no role """ user = self.get_test_user() self.client.force_login(user) self.set_up_session_params(user, lti_params=lti_params) def get_test_course(self): # pylint: disable=no-self-use """ Creates or retrieves a course object for testing. Returns the Course object. """ return Course.objects.get_or_create(edx_id=DEFAULT_TEST_COURSE_ID)[0] def get_test_assignment(self, edx_id=DEFAULT_ASSIGNMENT_EDX_ID): """ Creates or retrieves an assignment object for testing. Returns the Assignment object. Returns the Assignment object. @param edx_id: (optional[str]) edx_id for Assignment to be created/retrieved """ return Assignment.objects.get_or_create( edx_id=edx_id, course=self.get_test_course() )[0] def get_test_user(self, username=DEFAULT_USER_USERNAME): # pylint: disable=no-self-use """ Creates or retrieves test user (with no role). Returns the User object. """ return self.user_model.objects.get_or_create(username=username)[0] def get_test_student(self, username=DEFAULT_STUDENT_USERNAME): """ Creates or retrieves a user object for testing and attaches it to a course as a student. Returns the Student object. @param username: (optional[str]) username for User """ student_user, _ = self.user_model.objects.get_or_create(username=username) course = self.get_test_course() student, _ = Student.objects.get_or_create(course=course, user=student_user) return student def get_test_student_user(self, username=DEFAULT_STUDENT_USERNAME): """ Returns the User object attached to the Student from get_test_student() @param username: (optional[str]) username for User """ student = self.get_test_student(username=username) return student.user def get_test_grader(self, username=DEFAULT_GRADER_USERNAME): """ Creates or retrieves a user object for testing and attaches it to a course as a grader. Returns the Grader object. @param username: (optional[str]) username for User """ grader_user, _ = self.user_model.objects.get_or_create(username=username) course = self.get_test_course() grader, _ = Grader.objects.get_or_create(course=course, user=grader_user) return grader def get_test_grader_user(self): """ Returns the User object attached to the Grader from get_test_grader() """ grader = self.get_test_grader() return grader.user def get_test_admin_user(self): """ Creates or retrieves a user object for testing and attaches it to a course as an admin. Returns the User object. """ admin_user, _ = self.user_model.objects.get_or_create(username=DEFAULT_ADMIN_USERNAME) course = self.get_test_course() course.administrators.add(admin_user) return admin_user def get_test_submission(self, student_username=DEFAULT_STUDENT_USERNAME): """ Creates or retrieves a submission object for testing. Returns the Submission object. @param username: (optional[str]) username for student User attached to Submission """ return Submission.objects.get_or_create( student=self.get_test_student_user(username=student_username), assignment=self.get_test_assignment() )[0] def do_test_forbidden_view(self, url_path, role, method="get"): """ Runs general tests for view functions to ensure the view is forbidden for the role provided @param url_path: (str) url path for self.client.get() @param role: (st) role to log in as; must be in of [Roles.student, Roles.grader, Roles.admin] """ self.log_in_as(role) if method == "get": response = self.client.get(url_path, follow=True) else: # Assumes only "get" and "post" response = self.client.post(url_path, follow=True) self.assertEqual(response.status_code, 403) return response def do_test_successful_view(self, url_path, role, template=None, context_keys=None): # pylint: disable-msg=too-many-arguments """ Runs general tests for view functions to ensure 200 status code, template used, context variables @param url_path: (str) url path for self.client.get() @param role: (str) role to log in as; must be in of [Roles.student, Roles.grader, Roles.admin] @param template: (optional[str]) template path @param context_keys: (optional[list]) keys expected to be in context """ self.log_in_as(role) response = self.client.get(url_path, follow=True) self.assertEqual(response.status_code, 200) if template: self.assertTemplateUsed(response, template) if context_keys: for key in context_keys: self.assertTrue(key in response.context, msg="{key} not in context".format(key=key)) return response @staticmethod def get_test_file(filename="file.pdf", content_type="application/pdf"): """ Returns a SimpleUploadedFile for testing file uploads """ return SimpleUploadedFile( filename, bytearray("file contents", encoding="utf8"), content_type=content_type )
class ImportExportTests(TestCase): """Test CATMAID's import and export functionality. """ #fixtures = ['catmaid_project_stack_data'] def setUp(self): # We need a super user during import self.username = "******" self.password = "******" self.user = User.objects.create(username=self.username, is_superuser=True) self.user.set_password(self.password) self.user.save() self.test_project_id = 3 self.maxDiff = None self.client = Client() self.client.login(username=self.username, password=self.password) super(ImportExportTests, self).setUp(); def fake_authentication(self): self.client.force_login(self.user) def test_import_projects(self): """Import a set of new projects, stacks and stack groups. This tests only the actual import. Retrieving the data to import from different sources is not part of this test. """ project_url = 'https://catmaid-test/' data_folder = '/tmp/catmaid-test/' existing_projects = list(Project.objects.all()) existing_project_ids = [p.id for p in existing_projects] p1_config = { 'project': { 'title': 'test-no-stacks', } } p2_config = { 'project': { 'title': 'test-two-stacks', 'stacks': [ { # A basic stack, only with required information 'title': 'test-stack-1', 'dimension': '(7, 17, 23)', 'resolution': '(2, 3, 5)', 'zoomlevels': -1, 'mirrors': [{ 'title': 'test-mirror-1', 'fileextension': 'jpg' }] }, { # A basic stack with a little more information 'title': 'test-stack-2', 'dimension': '(7, 17, 23)', 'resolution': '(2, 3, 5)', 'zoomlevels': -1, 'mirrors': [{ 'title': 'test-mirror-2', 'fileextension': 'jpg', 'url': 'https://this.is.my.stack/' }] }, { # A stack with all optional properties 'title': 'test-stack-3', 'dimension': '(4, 34, 9)', 'resolution': '(1, 2, 3)', 'metadata': 'Test meta data', 'zoomlevels': -1, 'translation': '(10, 20, 30)', 'mirrors': [{ 'title': 'test-mirror-3', 'folder': 'abc/', 'fileextension': 'jpg', 'tile_width': 123, 'tile_height': 456, 'tile_source_type': 2, }], 'stackgroups': [{ # Add a single stack group with only this stack # in it. 'title': 'Test group 1', 'relation': 'view', }], } ] } } pre_projects = [ importer.PreProject(p1_config, project_url, data_folder), importer.PreProject(p2_config, project_url, data_folder), ] tags = [] permissions = [] default_tile_width = 256 default_tile_height = 512 default_tile_source_type = 5 default_position = 0 cls_graph_ids_to_link = [] remove_unref_stack_data = False imported, not_imported = importer.import_projects(self.user, pre_projects, tags, permissions, default_tile_width, default_tile_height, default_tile_source_type, cls_graph_ids_to_link, remove_unref_stack_data) self.assertListEqual(pre_projects, imported) self.assertListEqual([], not_imported) new_projects = list(Project.objects.exclude(id__in=existing_project_ids).order_by('title')) self.assertEqual(2, len(new_projects)) # Projects should be ordered by name, so the first project will be based # on p1_config. Test p1 first, it is not expected to have any stacks. p1 = new_projects[0] self.assertEqual(p1_config['project']['title'], p1.title) self.assertEqual(0, p1.stacks.all().count()) # Test p2. p2 = new_projects[1] self.assertEqual(p2_config['project']['title'], p2.title) p2_stacks = p2.stacks.all().order_by('title') self.assertEqual(3, len(p2_stacks)) p2cfg_stacks = p2_config['project']['stacks'] for n, p2s in enumerate(p2_stacks): stack = p2cfg_stacks[n] # Test required fields self.assertEqual(stack['title'], p2s.title) six.assertCountEqual(self, literal_eval(stack['dimension']), literal_eval(str(p2s.dimension))) six.assertCountEqual(self, literal_eval(stack['resolution']), literal_eval(str(p2s.resolution))) self.assertEqual(stack['zoomlevels'], p2s.num_zoom_levels) # Test mirrors mirrors = p2s.stackmirror_set.all().order_by('title') self.assertEqual(len(stack['mirrors']), len(mirrors)) for m, omirror in enumerate(mirrors): mirror = stack['mirrors'][m] self.assertEqual(mirror['title'], omirror.title) self.assertEqual(mirror['fileextension'], omirror.file_extension) # Test fields with potential default values self.assertEqual(mirror.get('position', default_position), omirror.position) self.assertEqual(mirror.get('tile_width', default_tile_width), omirror.tile_width) self.assertEqual(mirror.get('tile_height', default_tile_height), omirror.tile_height) self.assertEqual(mirror.get('tile_source_type', default_tile_source_type), omirror.tile_source_type) if 'url' in mirror: image_base = mirror['url'] else: image_base = urljoin(project_url, urljoin(mirror.get('path', ''), mirror.get('folder', ''))) self.assertEqual(image_base, omirror.image_base) # Test project-stack link ps = ProjectStack.objects.get(project=p2.id, stack=p2s) six.assertCountEqual(self, literal_eval(stack.get('translation', '(0,0,0)')), literal_eval(str(ps.translation))) # Test stack groups ostack_group_links = StackStackGroup.objects.filter(stack=p2s).order_by('stack__title') stack_groups = stack.get('stackgroups', []) self.assertEqual(len(ostack_group_links), len(stack_groups)) for m, sg_cfg in enumerate(stack_groups): ostack_group_link = ostack_group_links[m] ostack_group = ostack_group_link.stack_group self.assertEqual(sg_cfg['title'], ostack_group.title) self.assertEqual(sg_cfg['relation'], ostack_group_link.group_relation.name) self.assertEqual(sg_cfg.get('position', default_position), ostack_group_link.position) def test_import_export_projects(self): """Export all projects, stacks and stack groups (without class instance and tracing data). Make then sure, they match the fixture. """ p1_config = { 'project': { 'title': 'test-no-stacks', 'stacks': list(), } } p2_config = { 'project': { 'title': 'test-two-stacks', 'stacks': [{ 'broken_sections': [], 'title': 'test-stack-1', 'dimension': '(7, 17, 23)', 'resolution': '(2,3,5)', 'downsample_factors': None, 'orientation': 0, 'translation': '(0,0,0)', 'metadata': '', 'comment': 'Test comment', 'attribution': 'Test attribution', 'description': 'Simple test data', 'canary_location': '(0, 0, 0)', 'placeholder_color': '(0,0,0,1)', 'mirrors': [{ 'title': 'test-mirror-1', 'url': 'https://catmaid-test/', 'tile_height': 512, 'tile_width': 256, 'fileextension': 'jpg', 'tile_source_type': 5, 'position': 2 }] }, { 'broken_sections': [], 'comment': None, 'title': 'test-stack-2', 'dimension': '(7, 17, 23)', 'metadata': '', 'resolution': '(2,3,5)', 'downsample_factors': None, 'orientation': 0, 'translation': '(0,0,0)', 'attribution': None, 'description': '', 'canary_location': '(0, 0, 0)', 'placeholder_color': '(0.5,0.4,0.3,1)', 'mirrors': [{ 'title': 'test-mirror-2', 'position': 0, 'url': 'https://this.is.my.stack/', 'tile_height': 400, 'tile_width': 300, 'fileextension': 'jpg', 'tile_source_type': 5, }] }, { 'broken_sections': [], 'comment': None, 'title': 'test-stack-3', 'dimension': '(4, 34, 9)', 'metadata': 'Test meta data', 'resolution': '(1,2,3)', 'downsample_factors': None, 'orientation': 0, 'translation': '(0,0,0)', 'attribution': None, 'description': '', 'canary_location': '(1, 2, 3)', 'placeholder_color': '(0,0,0.3,0.1)', 'mirrors': [{ 'title': 'test-mirror-3', 'position': 0, 'url': 'https://catmaid-test/abc/', 'tile_height': 456, 'tile_width': 123, 'fileextension': 'jpg', 'tile_source_type': 2, }], 'stackgroups': [{ 'relation': 'view', 'title': u'Test group 1' }], }] } } project_url = 'https://catmaid-test/' data_folder = '/tmp/catmaid-test/' pre_projects = [ importer.PreProject(p1_config, project_url, data_folder), importer.PreProject(p2_config, project_url, data_folder), ] config = [p1_config, p2_config] tags = [] permissions = [] default_tile_width = 256 default_tile_height = 512 default_tile_source_type = 1 cls_graph_ids_to_link = [] remove_unref_stack_data = False # Make sure there are no existing projects or stacks Project.objects.all().delete() Stack.objects.all().delete() imported, not_imported = importer.import_projects(self.user, pre_projects, tags, permissions, default_tile_width, default_tile_height, default_tile_source_type, cls_graph_ids_to_link, remove_unref_stack_data) self.assertEqual(0, len(not_imported)) self.assertEqual(len(config), len(imported)) # Make sure we can see all projects for p in Project.objects.all(): assign_perm('can_browse', self.user, p) def strip_ids(d): """ Recursively, strip all 'id' fields of dictionaries. """ if type(d) == dict: if 'id' in d: d.pop('id') for _,v in d.items(): strip_ids(v) if type(d) == list: for v in d: strip_ids(v) def test_result(result): # Results come with IDs, which we don't have in our input data. Strip # them to be able to simply compare dictionaries. strip_ids(result) for cp, p in zip(config, result): # Convert potential stack tuples into lists (YAML parsing # results in tuples). if 'project' in p: if 'stacks' in p['project']: if type(p['project']['stacks']) == tuple: p['project']['stacks'] = list(p['project']['stacks']) self.assertDictEqual(cp, p) self.fake_authentication() def parse_list(d): for k in d: if type(d[k]) == tuple: d[k] = list(d[k]) return d # Export imported YAML data response = self.client.get('/projects/export') self.assertEqual(response.status_code, 200) result_yaml = yaml.load(response.content.decode('utf-8')) test_result(result_yaml) # Export imported JSON data response = self.client.get('/projects/export', HTTP_ACCEPT='application/json') self.assertEqual(response.status_code, 200) result_json = json.loads(response.content.decode('utf-8'), object_hook=parse_list) test_result(result_json)
def test_page_renders_with_correct_template(self): """Ensure the correct template is used to display the importer""" c = Client() c.force_login(self.user) response = c.get(reverse(self.test_url_name), user=self.user) self.assertTemplateUsed(response, 'wftda_importer/import.html')