def test_crear_codigo_desactiva_viejos(db): f = FiscalFactory() cod_original = CodigoReferido.objects.get() assert cod_original.activo is True nuevo = f.crear_codigo_de_referidos() assert nuevo.activo is True cod_original.refresh_from_db() assert cod_original.activo is False
def test_quiero_validar_gracias(db, client): f = FiscalFactory() s = client.session s['fiscal_id'] = f.id s.save() response = client.get(reverse('quiero-validar-gracias')) assert response.context['fiscal'] == f assert f.ultimo_codigo_url() in response.content.decode('utf8')
def test_esta_en_algun_grupo__ninguno(db, setup_groups): u_visualizador = UserFactory() visualizador = FiscalFactory(user=u_visualizador) g_visualizadores = Group.objects.get(name='visualizadores') g_visualizadores = Group.objects.get(name='validadores') u_visualizador.groups.add(g_visualizadores) assert not visualizador.esta_en_algun_grupo( ('unidades basicas', 'supervisores'))
def test_esta_en_algun_grupo__grupo_no_existente(db, setup_groups): u_visualizador = UserFactory() visualizador = FiscalFactory(user=u_visualizador) g_visualizadores = Group.objects.get(name='visualizadores') g_visualizadores = Group.objects.get(name='validadores') u_visualizador.groups.add(g_visualizadores) assert visualizador.esta_en_algun_grupo( ('grupo_no_existente', 'validadores'))
def test_generar_codigo_check_unicidad(db, mocker): mocked_sample = mocker.patch('fiscales.models.random.sample', return_value=['0', '0', '0', '0']) f = FiscalFactory() # el primero tiene codigo 0000 assert f.codigos_de_referidos.get().codigo == '0000' # el siguiente intenta 5 codigos. with pytest.raises(IntegrityError): FiscalFactory() assert mocked_sample.call_count == 6
def test_ciclo_de_vida_problemas_resolver(db): a = AttachmentFactory() m1 = MesaFactory() IdentificacionFactory(attachment=a, status='identificada', mesa=m1) # Está pendiente. assert a in Attachment.objects.sin_identificar() i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None) f = FiscalFactory() Problema.reportar_problema(f, 'reporte 1', ReporteDeProblema.TIPOS_DE_PROBLEMA.spam, identificacion=i1) assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None) Problema.reportar_problema(f, 'reporte 2', ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible, identificacion=i2) assert i1.invalidada == False assert i2.invalidada == False consumir_novedades_identificacion() # Se consolidó un problema. a.refresh_from_db() assert a.status == Attachment.STATUS.problema problema = i1.problemas.first().problema assert problema.estado == Problema.ESTADOS.pendiente # El attach no está entre los pendientes. assert a not in Attachment.objects.sin_identificar() problema.resolver(FiscalFactory().user) assert problema.estado == Problema.ESTADOS.resuelto i1.refresh_from_db() i2.refresh_from_db() # Las identificaciones están invalidadas. assert i1.invalidada == True assert i2.invalidada == True consumir_novedades_identificacion() # Se agrega una nueva identificación y se consolida. IdentificacionFactory(attachment=a, status='identificada', mesa=m1) consumir_novedades_identificacion() a.refresh_from_db() assert a.status == Attachment.STATUS.identificada assert a.mesa == m1
def test_siguiente_prioriza_categoria(db, settings): f = FiscalFactory() c = CategoriaFactory(prioridad=2) c2 = CategoriaFactory(prioridad=1) m1 = MesaFactory() AttachmentFactory(mesa=m1) mc1 = MesaCategoriaFactory( status=MesaCategoria.STATUS.parcial_sin_consolidar, categoria=c, mesa=m1, ) mc1.actualizar_coeficiente_para_orden_de_carga() m2 = MesaFactory() AttachmentFactory(mesa=m2) mc2 = MesaCategoriaFactory( categoria=c2, status=MesaCategoria.STATUS.parcial_sin_consolidar, mesa=m2, ) mc2.actualizar_coeficiente_para_orden_de_carga() # Se recibe la mc con categoria más prioritaria. assert MesaCategoria.objects.siguiente() == mc2 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc2.asignar_a_fiscal() # Luego la de la categoría menos prioritaria. assert MesaCategoria.objects.siguiente() == mc1
def test_identificacion_consolidada_ninguno(db): a = AttachmentFactory() m1 = MesaFactory() IdentificacionFactory(attachment=a, status='identificada', mesa=m1) i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None) f = FiscalFactory() Problema.reportar_problema(f, 'reporte 1', ReporteDeProblema.TIPOS_DE_PROBLEMA.spam, identificacion=i1) assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None) Problema.reportar_problema(f, 'reporte 2', ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible, identificacion=i2) assert a.identificacion_testigo is None cant_novedades = Identificacion.objects.filter(procesada=False).count() assert cant_novedades == 3 consumir_novedades_identificacion() # Se consolidó un problema. assert i1.problemas.first().problema.estado == Problema.ESTADOS.pendiente cant_novedades = Identificacion.objects.filter(procesada=False).count() assert cant_novedades == 0 assert a.identificacion_testigo is None
def test_fiscales_para_codigo(db): f = FiscalFactory() code_original = f.ultimo_codigo() # case unsensitive assert CodigoReferido.fiscales_para(code_original.lower()) == [(f, 100)] # por nombre y apellido. case unsensitive assert CodigoReferido.fiscales_para('otro', f.nombres.upper(), f.apellido.title()) == [(f, 75)] # codigo viejo f.crear_codigo_de_referidos() assert CodigoReferido.fiscales_para(code_original) == [(f, 25)] # codigo invalido assert CodigoReferido.fiscales_para('NADA') == [(None, 100)]
def test_siguiente_manda_a_parcial_si_es_requerido_sin_scheduler( db, client, setup_groups, settings): settings.MIN_COINCIDENCIAS_CARGAS = 1 m1 = MesaFactory() a1 = AttachmentFactory(mesa=m1, status=Identificacion.STATUS.identificada) m2 = MesaFactory() a2 = AttachmentFactory(mesa=m2, status=Identificacion.STATUS.identificada) mc1 = MesaCategoriaFactory(categoria__requiere_cargas_parciales=False, coeficiente_para_orden_de_carga=1, mesa=m1) mc2 = MesaCategoriaFactory(categoria__requiere_cargas_parciales=True, coeficiente_para_orden_de_carga=2, mesa=m2) fiscales = FiscalFactory.create_batch(2) # Da mc1 porque es más prioritaria. fiscal_client = fiscal_client_from_fiscal(client, fiscales[0]) response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[mc1.id]) # Cerramos la sesión para que el client pueda reutilizarse sin que nos diga # que ya estamos logueados. fiscal_client.logout() # mc1 fue asignada, ahora da mc2 fiscal_client = fiscal_client_from_fiscal(client, fiscales[1]) response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-parcial', args=[mc2.id])
def test_identificacion_consolidada_alguna(db): a = AttachmentFactory() m1 = MesaFactory() i1 = IdentificacionFactory(attachment=a, status='identificada', mesa=m1) IdentificacionFactory(attachment=a, status='problema', mesa=None) i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None) Problema.reportar_problema(FiscalFactory(), 'reporte 1', ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible, identificacion=i2) IdentificacionFactory(attachment=a, status='identificada', mesa=m1) assert a.identificacion_testigo is None cant_novedades = Identificacion.objects.filter(procesada=False).count() assert cant_novedades == 4 consumir_novedades_identificacion() # No se consolidó el problema. assert i2.problemas.first().problema.estado == Problema.ESTADOS.potencial cant_novedades = Identificacion.objects.filter(procesada=False).count() assert cant_novedades == 0 a.refresh_from_db() assert a.identificacion_testigo == i1 assert a.mesa == m1 assert a.status == Attachment.STATUS.identificada
def usr_unidad_basica(db): user = UserFactory() FiscalFactory(user=user) for nombre in ['unidades basicas', 'visualizadores']: g = Group.objects.create(name=nombre) g_unidades_basicas = Group.objects.get(name='unidades basicas') user.groups.add(g_unidades_basicas) return user
def test_validar_csv_fiscal_sin_permisos_suficientes(db): user = UserFactory() FiscalFactory(user=user) Group.objects.create(name='unidades basicas') g_visualizadores = Group.objects.create(name='visualizadores') user.groups.add(g_visualizadores) with pytest.raises(PermisosInvalidosError) as e: CSVImporter(PATH_ARCHIVOS_TEST + 'info_resultados_negativos.csv', user).validar() assert 'Su usuario no tiene los permisos necesarios' in str(e.value)
def test_quiero_ser_fiscal_form__email_repetido_en_la_base(db): fiscal = FiscalFactory() seccion = SeccionFactory() request_data = construir_request_data(seccion) request_data["email"] = fiscal.user.email request_data["email_confirmacion"] = fiscal.user.email form = QuieroSerFiscalForm(data=request_data) assert not form.is_valid() assert form.errors['email'][ 0] == QuieroSerFiscalForm.MENSAJE_ERROR_EMAIL_REPETIDO
def test_quiero_ser_fiscal_form__dni_repetido(db): seccion = SeccionFactory() request_data = construir_request_data(seccion) FiscalFactory(dni=request_data['dni']) form = QuieroSerFiscalForm(data=request_data) assert not form.is_valid() assert form.errors['dni'][ 0] == QuieroSerFiscalForm.MENSAJE_ERROR_DNI_REPETIDO
def test_liberacion_vuelve_al_ruedo(db, settings): """ Este test verifica que la acción del consolidador libera mesas que nunca recibieron resultados. """ f = FiscalFactory() c = CategoriaFactory(prioridad=1) m1 = MesaFactory() AttachmentFactory(mesa=m1) mc1 = MesaCategoriaFactory( status=MesaCategoria.STATUS.parcial_sin_consolidar, categoria=c, coeficiente_para_orden_de_carga=1.0, mesa=m1 ) m3 = MesaFactory() AttachmentFactory(mesa=m3) mc3 = MesaCategoriaFactory( categoria=c, status=MesaCategoria.STATUS.total_en_conflicto, coeficiente_para_orden_de_carga=2.0, mesa=m3 ) assert MesaCategoria.objects.siguiente() == mc1 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc1.asignar_a_fiscal() cant_asignaciones = mc1.cant_fiscales_asignados # Es como si de las varias asignaciones de la mc la última sea para el fiscal f f.asignar_mesa_categoria(mc1) # Como mc1 está muy asignada, ahora me propone mc3. assert MesaCategoria.objects.siguiente() == mc3 settings.TIMEOUT_TAREAS = 0 liberar_mesacategorias_y_attachments() # mc1 volvió al ruedo. assert MesaCategoria.objects.siguiente() == mc1 mc1.refresh_from_db() assert mc1.cant_fiscales_asignados == cant_asignaciones - 1
def test_referidos_post_confirma_conoce(fiscal_client, admin_user): fiscal = admin_user.fiscal referidos_ids = [ f.id for f in FiscalFactory.create_batch(2, referente=fiscal) ] assert fiscal.referidos.filter(referencia_confirmada=True).count() == 0 response = fiscal_client.post(reverse('referidos'), data={ 'conozco': '', 'referido': referidos_ids }) assert response.status_code == 200 assert fiscal.referidos.filter(referencia_confirmada=True).count() == 2
def test_identificacion_consolidada_calcula_orden_de_prioridad(db): mc1 = MesaCategoriaFactory() mesa = mc1.mesa mc2 = MesaCategoriaFactory(mesa=mesa) assert mc1.coeficiente_para_orden_de_carga is None assert mc2.coeficiente_para_orden_de_carga is None # Emulo consolidación. i = IdentificacionFactory(status='identificada', mesa=mc1.mesa, fiscal=FiscalFactory()) AttachmentFactory(status='identificada', mesa=mesa, identificacion_testigo=i) mc1.refresh_from_db() mc2.refresh_from_db() assert mc1.coeficiente_para_orden_de_carga is not None assert mc2.coeficiente_para_orden_de_carga is not None
def test_enviar_email_post(fiscal_client, admin_user, mailoutbox, settings): settings.DEFAULT_FROM_EMAIL = '*****@*****.**' f = FiscalFactory(nombres='Diego Armando') f.agregar_dato_de_contacto('email', '*****@*****.**') data = {'asunto': 'hola', 'template': '<p>Hola {{ fiscal.nombres }}</p>'} url = f"{reverse('enviar-email')}?ids={f.id}" response = fiscal_client.post(url, data) # se guardan variables de session assert fiscal_client.session.get('enviar_email_asunto') == 'hola' assert fiscal_client.session.get( 'enviar_email_template') == '<p>Hola {{ fiscal.nombres }}</p>' assert response.status_code == 302 assert len(mailoutbox) == 1 m = mailoutbox[0] assert m.subject == 'hola' assert 'Hola Diego Armando' in m.body # text version html = m.alternatives[0][0] # html version assert '<p>Hola Diego Armando</p>' in html assert html.startswith('<!doctype html>\n<html>\n <head>\n') assert m.from_email == '*****@*****.**' assert m.to == ['*****@*****.**']
def test_referidos_muestra_link_y_referidos(fiscal_client, admin_user): fiscal = admin_user.fiscal referidos_ids = { f.id for f in FiscalFactory.create_batch(2, referente=fiscal) } # otros fiscales no afectan FiscalFactory(referente=FiscalFactory()) assert set(fiscal.referidos.values_list('id', flat=True)) == referidos_ids response = fiscal_client.get(reverse('referidos')) assert response.status_code == 200 content = response.content.decode('utf8') form = response.context['form'] assert isinstance(form, ReferidoForm) assert form.initial['url'] == fiscal.ultimo_codigo_url() assert set(response.context['referidos'].values_list( 'id', flat=True)) == referidos_ids assert str(response.context['referidos'][0]) in content assert str(response.context['referidos'][1]) in content
def test_siguiente_prioriza_estado_y_luego_coeficiente(db, settings, setup_constance, django_assert_num_queries): f = FiscalFactory() c = CategoriaFactory(prioridad=1) m1 = MesaFactory() AttachmentFactory(mesa=m1) mc1 = MesaCategoriaFactory( status=MesaCategoria.STATUS.parcial_sin_consolidar, categoria=c, coeficiente_para_orden_de_carga=1.0, mesa=m1 ) m2 = MesaFactory() AttachmentFactory(mesa=m2) mc2 = MesaCategoriaFactory( categoria=c, status=MesaCategoria.STATUS.total_en_conflicto, coeficiente_para_orden_de_carga=99.0, mesa=m2 ) m3 = MesaFactory() AttachmentFactory(mesa=m3) mc3 = MesaCategoriaFactory( categoria=c, status=MesaCategoria.STATUS.total_en_conflicto, coeficiente_para_orden_de_carga=2.0, mesa=m3 ) with django_assert_num_queries(17): assert MesaCategoria.objects.siguiente() == mc1 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc1.asignar_a_fiscal() assert MesaCategoria.objects.siguiente() == mc3 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc3.asignar_a_fiscal() assert MesaCategoria.objects.siguiente() == mc2 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc2.asignar_a_fiscal() # A igualdad de asignaciones, se vuelven a repetir. assert MesaCategoria.objects.siguiente() == mc1 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc1.asignar_a_fiscal() assert MesaCategoria.objects.siguiente() == mc3 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc3.asignar_a_fiscal() assert MesaCategoria.objects.siguiente() == mc2
def test_enviar_email_get(fiscal_client, admin_user): fiscales_ids = ','.join(str(f.id) for f in FiscalFactory.create_batch(2)) url = f"{reverse('enviar-email')}?ids={fiscales_ids}" session = fiscal_client.session session.update({ 'enviar_email_asunto': 'foo', 'enviar_email_template': '{{ foo }}', }) session.save() response = fiscal_client.get(url) assert response.status_code == 200 form = response.context['form'] assert isinstance(form, EnviarEmailForm) assert 'Enviar Email a 2 fiscales' in response.content.decode('utf8') assert form.initial['asunto'] == 'foo' assert form.initial['template'] == '{{ foo }}'
def test_efecto_problema_descartado(db): fiscal_1 = nuevo_fiscal() a = AttachmentFactory() m1 = MesaFactory() i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None) f = FiscalFactory() Problema.reportar_problema(fiscal_1, 'reporte 1', ReporteDeProblema.TIPOS_DE_PROBLEMA.spam, identificacion=i1) assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial problema = i1.problemas.first().problema problema.descartar(nuevo_fiscal().user) from constance import config assert EventoScoringTroll.objects.filter(fiscal_afectado=fiscal_1).get( ).variacion == config.SCORING_TROLL_PROBLEMA_DESCARTADO
def test_siguiente_prioriza_seccion(db, settings): f = FiscalFactory() c = CategoriaFactory() # Si se pone # m1 = MesaFactory(circuito__seccion__prioridad_hasta_2=10000) # no funciona. # Intuyo que es porque en MesaFactory, el circuito se setea mediante un LazyAttribute, # y los seteos que van como argumentos de la Factory se estarían ejecutando antes de # que se apliquen los LazyAttribute. # Lo único que hice fue la prueba empírica de agregar "lugar_votacion__" antes, y ver que sí setea # la prioridad de la sección. No llegué a entender la documentación de factory boy en la medida necesaria. m1 = MesaFactory(lugar_votacion__circuito__seccion__prioridad_hasta_2=10000) AttachmentFactory(mesa=m1) mc1 = MesaCategoriaFactory( status=MesaCategoria.STATUS.parcial_sin_consolidar, categoria=c, mesa=m1, ) mc1.actualizar_coeficiente_para_orden_de_carga() m2 = MesaFactory(lugar_votacion__circuito__seccion__prioridad_hasta_2=42) AttachmentFactory(mesa=m2) mc2 = MesaCategoriaFactory( categoria=c, status=MesaCategoria.STATUS.parcial_sin_consolidar, mesa=m2, ) mc2.actualizar_coeficiente_para_orden_de_carga() assert mc1.percentil == 1 assert mc1.mesa.circuito.seccion.prioridad_hasta_2 == 10000 assert mc2.percentil == 1 assert mc2.mesa.circuito.seccion.prioridad_hasta_2 == 42 # Se recibe la mc de la sección más prioritaria. assert MesaCategoria.objects.siguiente() == mc2 for i in range(settings.MIN_COINCIDENCIAS_CARGAS): mc2.asignar_a_fiscal() # Luego la de la sección con prioridad menos prioritaria. assert MesaCategoria.objects.siguiente() == mc1
def test_siguiente_accion_redirige_a_cargar_resultados_sin_scheduler( db, settings, client, setup_groups): c1 = CategoriaFactory() c2 = CategoriaFactory() m1 = MesaFactory(categorias=[c1]) IdentificacionFactory( mesa=m1, status='identificada', source=Identificacion.SOURCES.csv, ) m2 = MesaFactory(categorias=[c1, c2]) assert MesaCategoria.objects.count() == 3 IdentificacionFactory( mesa=m2, status='identificada', source=Identificacion.SOURCES.csv, ) # Ambas consolidadas vía csv. consumir_novedades_identificacion() # Los fiscales que voy a usar. fiscales = FiscalFactory.create_batch(20) indice_fiscal = 0 m1c1 = MesaCategoria.objects.get(mesa=m1, categoria=c1) for i in range(settings.MIN_COINCIDENCIAS_CARGAS): fiscal_client = fiscal_client_from_fiscal(client, fiscales[indice_fiscal]) indice_fiscal += 1 response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[m1c1.id]) # Cerramos la sesión para que el client pueda reutilizarse sin que nos diga # que ya estamos logueados. fiscal_client.logout() # Como m1c1 ya fue pedida por suficientes fiscales, # se pasa a la siguiente mesacategoría. m2c1 = MesaCategoria.objects.get(mesa=m2, categoria=c1) for i in range(settings.MIN_COINCIDENCIAS_CARGAS): fiscal_client = fiscal_client_from_fiscal(client, fiscales[indice_fiscal]) indice_fiscal += 1 response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[m2c1.id]) fiscal_client.logout() # Ahora la tercera. m2c2 = MesaCategoria.objects.get(mesa=m2, categoria=c2) for i in range(settings.MIN_COINCIDENCIAS_CARGAS): fiscal_client = fiscal_client_from_fiscal(client, fiscales[indice_fiscal]) indice_fiscal += 1 response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[m2c2.id]) fiscal_client.logout() # Ya no hay actas nuevas, vuelta a empezar. fiscal_client = fiscal_client_from_fiscal(client, fiscales[indice_fiscal]) indice_fiscal += 1 response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[m1c1.id]) fiscal_client.logout() # Se libera una. m2c2.desasignar_a_fiscal() fiscal_client = fiscal_client_from_fiscal(client, fiscales[indice_fiscal]) indice_fiscal += 1 response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-total', args=[m2c2.id])
def nuevo_fiscal(): usuario = UserFactory() fiscal = FiscalFactory(user=usuario) return fiscal
def test_ultimo_codigo_url(db, settings, mocker): settings.FULL_SITE_URL = 'https://site.com' mocker.patch('fiscales.models.Fiscal.ultimo_codigo', return_value='D10S') f = FiscalFactory() assert f.ultimo_codigo_url() == 'https://site.com' + reverse( 'quiero-validar', args=['D10S'])
def test_esta_en_algun_grupo(db, setup_groups, admin_user): admin = FiscalFactory(user=admin_user) assert admin.esta_en_algun_grupo(('validadores', )) assert admin.esta_en_algun_grupo(('validadores', 'unidades basicas'))
def test_fiscal_crea_codigo(db): FiscalFactory.create_batch(4) assert CodigoReferido.objects.count() == 4