def test_identificacion_problema_create_view_post_no_ajax( fiscal_client, mocker): info = mocker.patch('adjuntos.views.messages.info') a = AttachmentFactory() data = { 'status': 'problema', 'tipo_de_problema': 'falta_lista', 'descripcion': 'Un problema' } # ajax post url = reverse('asignar-problema', args=[a.id]) response = fiscal_client.post(url, data) assert response.status_code == 302 assert info.call_args[0][ 1] == 'Gracias por el reporte. Ahora pasamos a la siguiente acta.' assert response.url == reverse('siguiente-accion') # estrictamente, acá no se crea ningun problema assert not a.problemas.exists()
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_troll_total_consolidada_dc_a_total_sin_consolidar(db, settings): fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() presi = CategoriaFactory() mesa_1 = MesaFactory(categorias=[presi]) mesa_categoria_1 = MesaCategoria.objects.filter(mesa=mesa_1, categoria=presi).first() attach_1 = AttachmentFactory() identificar(attach_1, mesa_1, fiscal_1) identificar(attach_1, mesa_1, fiscal_2) refrescar_data([ presi, fiscal_1, fiscal_2, fiscal_3, mesa_1, mesa_categoria_1, attach_1 ]) assert not fiscal_1.troll assert not fiscal_2.troll nueva_carga(mesa_categoria_1, fiscal_1, [20, 35], Carga.TIPOS.parcial) nueva_carga(mesa_categoria_1, fiscal_2, [20, 35], Carga.TIPOS.parcial) consumir_novedades_carga() refrescar_data([mesa_categoria_1]) assert mesa_categoria_1.status == MesaCategoria.STATUS.parcial_consolidada_dc nueva_carga(mesa_categoria_1, fiscal_3, [20, 35], Carga.TIPOS.total) nueva_carga(mesa_categoria_1, fiscal_1, [20, 35], Carga.TIPOS.total) consumir_novedades_carga() refrescar_data([mesa_categoria_1]) assert mesa_categoria_1.status == MesaCategoria.STATUS.total_consolidada_dc assert Carga.objects.filter(invalidada=True).count() == 0 aplicar_marca_troll(fiscal_3) consumir_novedades_identificacion() consumir_novedades_carga() refrescar_data([mesa_categoria_1, fiscal_3]) assert mesa_categoria_1.status == MesaCategoria.STATUS.total_sin_consolidar assert Carga.objects.filter(invalidada=True).count() == 1
def test_scheduler_orden_estandar(db, settings): # Creamos 5 attachments sin identificar attachments = AttachmentFactory.create_batch( 5, status=Attachment.STATUS.sin_identificar) c1 = CategoriaFactory(sensible=True) c2 = CategoriaFactory(sensible=True) 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() with override_config(COEFICIENTE_IDENTIFICACION_VS_CARGA=10): scheduler() assert ColaCargasPendientes.largo_cola() == 16 # Las primeras seis tareas son de carga de votos. for i in range(6): consumir(False) assert ColaCargasPendientes.largo_cola() == 10 # las siguientes diez son identificaciones. for i in range(10): consumir() assert ColaCargasPendientes.largo_cola() == 0 # Ya no queda nada en la cola. (mc, attachment) = ColaCargasPendientes.siguiente_tarea(fiscal=None) assert mc is None and attachment is None
def test_asociacion_attachment_con_antitrolling(db, settings): """ Se simula que se asocia un Attachment a una mesa, usando la función de consolidación. Se comprueba que el efecto sobre el scoring de troll de los fiscales que hicieron identificaciones es el correcto. """ settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_IDENTIFICACION_PROBLEMA = 2 with override_config( SCORING_TROLL_IDENTIFICACION_DISTINTA_A_CONFIRMADA=180, SCORING_TROLL_DESCUENTO_ACCION_CORRECTA=28): fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() fiscal_4 = nuevo_fiscal() mesa_1 = MesaFactory() mesa_2 = MesaFactory() attach = AttachmentFactory() # Empezamos con dos identificaciones a mesas distintas identificar(attach, mesa_1, fiscal_1) identificar(attach, mesa_2, fiscal_3) # Hasta acá no debería asociarse la mesa, ergo no se afecta el scoring troll de ningun fiscal consolidar_identificaciones(attach) for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4]: fiscal.refresh_from_db() for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4]: assert fiscal.scoring_troll() == 0 # se agregan dos nuevas identificaciones: el fiscal 2 identifica la misma mesa que el 1, el fiscal 4 reporta un problema identificar(attach, mesa_1, fiscal_2) reportar_problema_attachment(attach, fiscal_4) # ahora si deberia asociarse la mesa, y como consecuencia, # aumentar el scoring troll para los fiscales 3 y 4 que identificaron distinto a lo que se decidio consolidar_identificaciones(attach) for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4]: fiscal.refresh_from_db() assert fiscal_1.scoring_troll() == -28 assert fiscal_2.scoring_troll() == -28 assert fiscal_3.scoring_troll() == 180 assert fiscal_4.scoring_troll() == 180
def test_carga_parcial_consolidada_dc(db, settings): fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() presi = CategoriaFactory() mesa_1 = MesaFactory(categorias=[presi]) mesa_categoria_1 = MesaCategoria.objects.filter(mesa=mesa_1, categoria=presi).first() attach_1 = AttachmentFactory() assert mesa_categoria_1.status == MesaCategoria.STATUS.sin_cargar identificar(attach_1, mesa_1, fiscal_1) identificar(attach_1, mesa_1, fiscal_2) refrescar_data( [presi, fiscal_1, fiscal_2, mesa_1, mesa_categoria_1, attach_1]) assert not fiscal_1.troll assert not fiscal_2.troll assert Identificacion.objects.filter(procesada=False).count() == 2 consumir_novedades_identificacion() refrescar_data([mesa_categoria_1, mesa_1, attach_1]) assert Identificacion.objects.filter(procesada=False).count() == 0 nueva_carga(mesa_categoria_1, fiscal_1, [20, 15], Carga.TIPOS.parcial) consumir_novedades_carga() refrescar_data([mesa_categoria_1]) assert mesa_categoria_1.status == MesaCategoria.STATUS.parcial_sin_consolidar nueva_carga(mesa_categoria_1, fiscal_2, [20, 15], Carga.TIPOS.parcial) refrescar_data([mesa_categoria_1]) assert Carga.objects.filter(procesada=False).count() == 1 consumir_novedades_carga() refrescar_data([mesa_categoria_1]) assert mesa_categoria_1.status == MesaCategoria.STATUS.parcial_consolidada_dc assert Carga.objects.filter(procesada=False).count() == 0
def test_ciclo_de_vida_problemas_descartar(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 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 problema.descartar(FiscalFactory().user) assert problema.estado == Problema.ESTADOS.descartado 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_registro_evento_scoring_identificacion_incorrecta(db): """ Se comprueba que un EventoScoringTroll se genere con los valores correctos. """ fiscal = nuevo_fiscal() attach = AttachmentFactory() identi = reportar_problema_attachment(attach, fiscal) cantidad_eventos_antes = EventoScoringTroll.objects.count() aumentar_scoring_troll_identificacion(100, identi) assert EventoScoringTroll.objects.count() == cantidad_eventos_antes + 1 assert fiscal.eventos_scoring_troll.count() == 1 evento = fiscal.eventos_scoring_troll.first() assert evento.motivo == EventoScoringTroll.MOTIVOS.identificacion_attachment_distinta_a_confirmada assert evento.mesa_categoria is None assert evento.attachment == attach assert evento.automatico assert evento.actor is None assert evento.fiscal_afectado == fiscal assert evento.variacion == 100
def test_elegir_acta_mesas_redirige(db, fiscal_client): assert Mesa.objects.count() == 0 assert VotoMesaReportado.objects.count() == 0 c = CircuitoFactory() e1 = EleccionFactory() e2 = EleccionFactory() m1 = AttachmentFactory(mesa__eleccion=[e1], mesa__lugar_votacion__circuito=c).mesa e2 = EleccionFactory() m2 = AttachmentFactory(mesa__eleccion=[e1, e2], mesa__lugar_votacion__circuito=c).mesa assert m1.orden_de_carga == 1 assert m2.orden_de_carga == 2 response = fiscal_client.get(reverse('elegir-acta-a-cargar')) assert response.status_code == 302 assert response.url == reverse('mesa-cargar-resultados', args=[e1.id, m1.numero]) # como m1 queda en periodo de "taken" (aunque no se haya ocupado aun) # se pasa a la siguiente mesa response = fiscal_client.get(reverse('elegir-acta-a-cargar')) assert response.status_code == 302 assert response.url == reverse('mesa-cargar-resultados', args=[e1.id, m2.numero]) # se carga esa eleccion VotoMesaReportadoFactory(mesa=m2, eleccion=e1, opcion=e1.opciones.first(), votos=1) # FIX ME . El periodo de taken deberia ser *por eleccion*. # en este escenario donde esta lockeado la mesa para la eleccion 1, pero no se está # cargando la mesa 2, un dataentry queda idle response = fiscal_client.get(reverse('elegir-acta-a-cargar')) assert response.status_code == 200 # no hay actas m2.taken = None m2.save() response = fiscal_client.get(reverse('elegir-acta-a-cargar')) assert response.status_code == 302 assert response.url == reverse('mesa-cargar-resultados', args=[e2.id, m2.numero])
def test_efecto_consolidar_asociacion_attachment(db, settings): """ Se comprueba que el efecto de afectar el scoring de troll a partir de la asociacion de un Attachment a una Mesa sea el correcto. O sea, que se aumente el scoring de los fiscales que hicieron identificaciones distintas a la aceptada, y que no aumente el scoring de los fiscales que hicieron la identificacion aceptada. """ with override_config( SCORING_TROLL_IDENTIFICACION_DISTINTA_A_CONFIRMADA=180, SCORING_TROLL_DESCUENTO_ACCION_CORRECTA=40): fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() fiscal_4 = nuevo_fiscal() mesa_1 = MesaFactory() mesa_2 = MesaFactory() attach = AttachmentFactory() # los cuatro fiscales hacen una identificacion sobre el mismo attachment # los fiscales 1 y 2 hacen la identificacion que se va a aceptar, a la mesa 1 # el fiscal 3 identifica a una mesa distinta # el fiscal 4 reporta un problema identificar(attach, mesa_1, fiscal_1) identificar(attach, mesa_1, fiscal_2) identificar(attach, mesa_2, fiscal_3) reportar_problema_attachment(attach, fiscal_4) # se espera que se generen dos eventos, para los fiscales 3 y 4 que identificaron distinto # a la mesa que se indica como asociada al attachment cantidad_eventos_antes = EventoScoringTroll.objects.count() efecto_scoring_troll_asociacion_attachment(attach, mesa_1) for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4]: fiscal.refresh_from_db() assert EventoScoringTroll.objects.count() == cantidad_eventos_antes + 4 assert fiscal_1.scoring_troll() == -40 assert fiscal_2.scoring_troll() == -40 assert fiscal_3.scoring_troll() == 180 assert fiscal_4.scoring_troll() == 180
def test_registro_evento_scoring_identificacion_correcta(db): """ Se comprueba que un EventoScoringTroll correspondiente a una identificación correcta, se genere con los valores correctos. """ fiscal = nuevo_fiscal() attach = AttachmentFactory() mesa = MesaFactory() identi = identificar(attach, mesa, fiscal) cantidad_eventos_antes = EventoScoringTroll.objects.count() disminuir_scoring_troll_identificacion(80, identi) assert EventoScoringTroll.objects.count() == cantidad_eventos_antes + 1 assert fiscal.eventos_scoring_troll.count() == 1 evento = fiscal.eventos_scoring_troll.first() assert evento.motivo == EventoScoringTroll.MOTIVOS.identificacion_aceptada assert evento.mesa_categoria is None assert evento.attachment == attach assert evento.automatico assert evento.actor is None assert evento.fiscal_afectado == fiscal assert evento.variacion == -80
def test_identificacion_create_view_post(fiscal_client, admin_user): m1 = MesaFactory() a = AttachmentFactory() admin_user.fiscal.asignar_attachment(a) a.asignar_a_fiscal() data = { 'mesa': m1.numero, 'circuito': m1.circuito.numero, 'seccion': m1.circuito.seccion.numero, 'distrito': m1.circuito.seccion.distrito.id, } response = fiscal_client.post(reverse('asignar-mesa', args=[a.id]), data) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('siguiente-accion') assert a.identificaciones.count() == 1 i = a.identificaciones.first() assert i.status == Identificacion.STATUS.identificada assert i.mesa == m1 assert i.fiscal == admin_user.fiscal # La identificación todavía no está consolidada. a.refresh_from_db() assert a.identificacion_testigo is None assert not m1.attachments.exists() assert a.cant_fiscales_asignados == 0
def test_avance_de_carga_mesas_con_carga_csv_sin_fotos(db, settings): # settings settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_CARGA = 2 # una categoria con cuatro opciones, dos prioritarias, dos no prioritarias pv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) # un circuito con 10 mesas de 100, 110, ..., 290 votantes. Total 1450 seccion_1, circuito_1, lugar_votacion_1 = crear_seccion("Luján oeste") [mesas_1] = crear_mesas([lugar_votacion_1], [pv], 10) for ix in range(len(mesas_1)): mesas_1[ix].electores = 100 + ix * 10 mesas_1[ix].save(update_fields=['electores']) # dos fiscales fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() # identifico totalmente 6 mesas, parcialmente dos mesas attachs = AttachmentFactory.create_batch(30) for ix in range(6): identificar(attachs[ix], mesas_1[ix], fiscal_1) identificar(attachs[ix], mesas_1[ix], fiscal_2) identificar(attachs[6], mesas_1[6], fiscal_1) identificar(attachs[7], mesas_1[7], fiscal_1) consumir_novedades_identificacion() # dos cargas parciales nueva_carga(mesacat(mesas_1[0], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_1[1], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) # tres cargas totales desde CSV de una mesa sin identificar (la última), una parcialmente identificada, una identificada nueva_carga(mesacat(mesas_1[9], pv), fiscal_1, [50, 30, 20, 10], Carga.TIPOS.total, Carga.SOURCES.csv) nueva_carga(mesacat(mesas_1[6], pv), fiscal_1, [50, 30, 20, 10], Carga.TIPOS.total, Carga.SOURCES.csv) nueva_carga(mesacat(mesas_1[2], pv), fiscal_1, [50, 30, 20, 10], Carga.TIPOS.total, Carga.SOURCES.csv) consumir_novedades_carga() # podemos mirar vorwaerts = AvanceDeCarga(NIVELES_DE_AGREGACION.circuito, [circuito_1.id]) resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 1, 180, 10, 12.41) verificar_resultado(resultados.sin_identificar_con_cargas(), 1, 190, 10, 13.1) verificar_resultado(resultados.en_identificacion_sin_cargas(), 1, 170, 10, 11.72) verificar_resultado(resultados.en_identificacion_con_cargas(), 1, 160, 10, 11.03) verificar_resultado(resultados.sin_cargar(), 3, 420, 30, 28.97) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 2, 210, 20, 14.48) verificar_resultado(resultados.carga_parcial_consolidada_csv(), 0, 0, 0, 0) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 0, 0, 0, 0) verificar_resultado(resultados.carga_total_sin_consolidar(), 0, 0, 0, 0) verificar_resultado(resultados.carga_total_consolidada_csv(), 3, 470, 30, 32.41) verificar_resultado(resultados.carga_total_consolidada_dc(), 0, 0, 0, 0)
def test_avance_de_carga_combinando_dc_y_csv(db, settings): # settings settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_CARGA = 2 # una categoria con cuatro opciones, dos prioritarias, dos no prioritarias pv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) # un circuito con 20 mesas de 100, 110, ..., 290 votantes. Total 3900 seccion_1, circuito_1, lugar_votacion_1 = crear_seccion("Luján oeste") [mesas_1] = crear_mesas([lugar_votacion_1], [pv], 20) for ix in range(len(mesas_1)): mesas_1[ix].electores = 100 + ix * 10 mesas_1[ix].save(update_fields=['electores']) # dos fiscales fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() # identifico 18 mesas attachs = AttachmentFactory.create_batch(30) for ix in range(18): identificar(attachs[ix], mesas_1[ix], fiscal_1) identificar(attachs[ix], mesas_1[ix], fiscal_2) consumir_novedades_identificacion() # doble carga total coincidente de 4 mesas for ix in range(4): nueva_carga(mesacat(mesas_1[ix], pv), fiscal_1, [50, 30, 20, 10], Carga.TIPOS.total) nueva_carga(mesacat(mesas_1[ix], pv), fiscal_2, [50, 30, 20, 10], Carga.TIPOS.total) # cinco cargas totales desde CSV for ix in range(5): nueva_carga(mesacat(mesas_1[4 + ix], pv), fiscal_1, [50, 30, 20, 10], Carga.TIPOS.total, Carga.SOURCES.csv) # doble carga parcial coincidente de 3 mesas for ix in range(3): nueva_carga(mesacat(mesas_1[9 + ix], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_1[9 + ix], pv), fiscal_2, [50, 30], Carga.TIPOS.parcial) # dos cargas parciales desde CSV nueva_carga(mesacat(mesas_1[12], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial, Carga.SOURCES.csv) nueva_carga(mesacat(mesas_1[13], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial, Carga.SOURCES.csv) # una carga parcial nueva_carga(mesacat(mesas_1[14], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) consumir_novedades_carga() # podemos mirar vorwaerts = AvanceDeCarga(NIVELES_DE_AGREGACION.circuito, [circuito_1.id]) resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 20, 3900, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 2, 570, 10, 14.62) verificar_resultado(resultados.sin_cargar(), 3, 780, 15, 20) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 1, 240, 5, 6.15) verificar_resultado(resultados.carga_parcial_consolidada_csv(), 2, 450, 10, 11.54) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 3, 600, 15, 15.38) verificar_resultado(resultados.carga_total_sin_consolidar(), 0, 0, 0, 0) verificar_resultado(resultados.carga_total_consolidada_csv(), 5, 800, 25, 20.51) verificar_resultado(resultados.carga_total_consolidada_dc(), 4, 460, 20, 11.79)
def test_avance_de_carga_dos_circuitos(db, settings): # settings settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_CARGA = 2 # dos categorías con cuatro opciones, dos prioritarias, dos no prioritarias pv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) gv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) # un circuito con 10 mesas de 100, 110, ..., 190 votantes. Total 1450 seccion_1, circuito_1, lugar_votacion_1 = crear_seccion("Luján oeste") [mesas_1] = crear_mesas([lugar_votacion_1], [pv, gv], 10) for ix in range(len(mesas_1)): mesas_1[ix].electores = 100 + ix * 10 mesas_1[ix].save(update_fields=['electores']) # otro circuito con 20 mesas de 200 votantes. Total 4000 seccion_2, circuito_2, lugar_votacion_2 = crear_seccion("Mercedes") [mesas_2] = crear_mesas([lugar_votacion_2], [pv, gv], 20) for ix in range(len(mesas_2)): mesas_2[ix].electores = 200 mesas_2[ix].save(update_fields=['electores']) fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() # identifico todas las mesas salvo dos de la sección 2 attachs = AttachmentFactory.create_batch(30) for ix in range(10): identificar(attachs[ix], mesas_1[ix], fiscal_1) identificar(attachs[ix], mesas_1[ix], fiscal_2) for ix in range(18): identificar(attachs[ix + 10], mesas_2[ix], fiscal_1) identificar(attachs[ix + 10], mesas_2[ix], fiscal_2) consumir_novedades_identificacion() # sección 1 # doble carga parcial coincidente de 6 mesas pv y 2 mesas gv for ix in range(6): nueva_carga(mesacat(mesas_1[ix], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_1[ix], pv), fiscal_2, [50, 30], Carga.TIPOS.parcial) for ix in range(2): nueva_carga(mesacat(mesas_1[ix], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_1[ix], gv), fiscal_2, [55, 25], Carga.TIPOS.parcial) # una carga parcial de una mesa pv y tres gv nueva_carga(mesacat(mesas_1[6], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) for ix in range(3): nueva_carga(mesacat(mesas_1[ix + 2], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) consumir_novedades_carga() # sección 2 # doble carga parcial coincidente de 15 mesas pv y 12 gv for ix in range(15): nueva_carga(mesacat(mesas_2[ix], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_2[ix], pv), fiscal_2, [50, 30], Carga.TIPOS.parcial) for ix in range(12): nueva_carga(mesacat(mesas_2[ix], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas_2[ix], gv), fiscal_2, [55, 25], Carga.TIPOS.parcial) # una carga parcial 6 mesas gv for ix in range(6): nueva_carga(mesacat(mesas_2[ix + 12], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) consumir_novedades_carga() # resultados circuito 1 vorwaerts = AvanceDeCarga(NIVELES_DE_AGREGACION.circuito, [circuito_1.id]) # categoría pv resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.sin_cargar(), 3, 540, 30, 37.24) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 1, 160, 10, 11.03) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 6, 750, 60, 51.72) # categoría gv resultados = vorwaerts.get_resultados(gv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.sin_cargar(), 5, 850, 50, 58.62) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 3, 390, 30, 26.9) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 2, 210, 20, 14.48) # resultados circuito 2 vorwaerts = AvanceDeCarga(NIVELES_DE_AGREGACION.circuito, [circuito_2.id]) # categoría pv resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 20, 4000, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 2, 400, 10, 10) verificar_resultado(resultados.sin_cargar(), 3, 600, 15, 15) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 0, 0, 0, 0) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 15, 3000, 75, 75) # categoría gv resultados = vorwaerts.get_resultados(gv) verificar_resultado(resultados.total(), 20, 4000, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 2, 400, 10, 10) verificar_resultado(resultados.sin_cargar(), 0, 0, 0, 0) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 6, 1200, 30, 30) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 12, 2400, 60, 60)
def test_avance_de_carga_dos_categorias(db, settings): # settings settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_CARGA = 2 # dos categoríasas con cuatro opciones, dos prioritarias, dos no prioritarias pv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) gv = nueva_categoria(["a1", "a2"], ["b1", "b2"]) # 10 mesas de 100, 110, ..., 190 votantes. Total 1450 seccion, circuito, lugar_votacion = crear_seccion("Luján oeste") [mesas] = crear_mesas([lugar_votacion], [pv, gv], 10) for ix in range(len(mesas)): mesas[ix].electores = 100 + ix * 10 mesas[ix].save(update_fields=['electores']) fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() # identifico 9 mesas attachs = AttachmentFactory.create_batch(10) for ix in range(9): identificar(attachs[ix], mesas[ix], fiscal_1) identificar(attachs[ix], mesas[ix], fiscal_2) consumir_novedades_identificacion() # doble carga parcial coincidente de 6 mesas pv y 2 mesas gv for ix in range(6): nueva_carga(mesacat(mesas[ix], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas[ix], pv), fiscal_2, [50, 30], Carga.TIPOS.parcial) for ix in range(2): nueva_carga(mesacat(mesas[ix], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) nueva_carga(mesacat(mesas[ix], gv), fiscal_2, [55, 25], Carga.TIPOS.parcial) # una carga parcial de una mesa pv y tres gv nueva_carga(mesacat(mesas[6], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) for ix in range(3): nueva_carga(mesacat(mesas[ix + 2], gv), fiscal_1, [55, 25], Carga.TIPOS.parcial) consumir_novedades_carga() # resultados vorwaerts = AvanceDeCarga() # categoría pv resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 1, 190, 10, 13.1) verificar_resultado(resultados.en_identificacion_sin_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.sin_cargar(), 2, 350, 20, 24.14) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 1, 160, 10, 11.03) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 6, 750, 60, 51.72) # categoría gv resultados = vorwaerts.get_resultados(gv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 1, 190, 10, 13.1) verificar_resultado(resultados.en_identificacion_sin_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.sin_cargar(), 4, 660, 40, 45.52) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 3, 390, 30, 26.9) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 2, 210, 20, 14.48)
def test_datos_preidentificaciones(db, settings): settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.DISTRITO_PBA = '2' # 50 mesas: 20 pba, 15 caba, 15 catamarca data = DataTresDistritos(settings.DISTRITO_PBA) # 20 preidentificaciones preidents_pba = [PreidentificacionFactory(distrito=data.distrito_pba) for ix in range(12)] preidents_caba = [PreidentificacionFactory(distrito=data.distrito_caba) for ix in range(8)] # 40 fotos: # - 14 / 5 / 2 identificadas a mesas pba / caba / catamarca # - 3 con problemas # - 6 en proceso de identificación # - 10 sin acciones fotos = [] for ix in range(40): foto = AttachmentFactory() fotos.append(foto) if (ix < 14): identificar(foto, data.mesas_pba[ix], data.fiscales[0]) identificar(foto, data.mesas_pba[ix], data.fiscales[1]) if (ix < 5): foto.pre_identificacion = preidents_pba[ix] foto.save(update_fields=['pre_identificacion']) elif (ix < 19): identificar(foto, data.mesas_caba[ix-14], data.fiscales[2]) identificar(foto, data.mesas_caba[ix-14], data.fiscales[3]) if (ix < 17): foto.pre_identificacion = preidents_caba[ix-14] foto.save(update_fields=['pre_identificacion']) elif (ix < 21): identificar(foto, data.mesas_cat[ix-19], data.fiscales[4]) identificar(foto, data.mesas_cat[ix-19], data.fiscales[5]) elif (ix < 24): reportar_problema_attachment(foto, data.fiscales[6]) reportar_problema_attachment(foto, data.fiscales[7]) elif (ix < 30): identificar(foto, data.mesas_pba[ix-10], data.fiscales[8]) if (ix < 26): foto.pre_identificacion = preidents_pba[ix-19] foto.save(update_fields=['pre_identificacion']) elif (ix < 35): foto.pre_identificacion = preidents_pba[ix-23] foto.save(update_fields=['pre_identificacion']) elif (ix < 40): foto.pre_identificacion = preidents_caba[ix-32] foto.save(update_fields=['pre_identificacion']) consumir_novedades() generador_nacional = GeneradorDatosPreidentificaciones() generador_pba = GeneradorDatosPreidentificaciones( PreIdentificacion.objects.filter(distrito__numero=settings.DISTRITO_PBA)) generador_nacional.calcular() generador_pba.calcular() assert generador_nacional.cantidad_total == 20 assert generador_nacional.identificadas == 8 assert generador_nacional.sin_identificar == 12 assert generador_pba.cantidad_total == 12 assert generador_pba.identificadas == 5 assert generador_pba.sin_identificar == 7
def test_sin_identificar_excluye_otros_estados(db): AttachmentFactory(status='spam') AttachmentFactory(status='invalida') AttachmentFactory(status='identificada') a = AttachmentFactory(status=Attachment.STATUS.sin_identificar) assert set(Attachment.objects.sin_identificar()) == {a}
def test_efecto_marcar_fiscal_como_troll(db): """ Se comprueba que al marcar un fiscal como troll, las cargas e identificaciones que hizo quedan invalidadas. """ fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() fiscal_4 = nuevo_fiscal() categoria_1 = nueva_categoria(["o1", "o2", "o3"]) categoria_2 = nueva_categoria(["p1", "p2", "p3"]) mesa_1 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_2 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_3 = MesaFactory(categorias=[categoria_1]) attach_1 = AttachmentFactory() attach_2 = AttachmentFactory() attach_3 = AttachmentFactory() attach_4 = AttachmentFactory() ident_1_1 = identificar(attach_1, mesa_1, fiscal_1) ident_1_2 = identificar(attach_1, mesa_1, fiscal_2) ident_1_3 = reportar_problema_attachment(attach_1, fiscal_3) ident_2_2 = identificar(attach_2, mesa_2, fiscal_2) ident_2_3 = identificar(attach_2, mesa_3, fiscal_3) ident_3_1 = reportar_problema_attachment(attach_3, fiscal_1) ident_3_4 = identificar(attach_3, mesa_3, fiscal_4) ident_4_2 = identificar(attach_4, mesa_2, fiscal_2) ident_4_4 = reportar_problema_attachment(attach_4, fiscal_4) mesa_categoria_1_1 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_1).first() carga_1_1_1 = nueva_carga(mesa_categoria_1_1, fiscal_1, [30, 20, 10]) carga_1_1_2 = nueva_carga(mesa_categoria_1_1, fiscal_2, [30, 20, 10]) mesa_categoria_1_2 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_2).first() carga_1_2_1 = nueva_carga(mesa_categoria_1_2, fiscal_1, [30, 20, 10]) carga_1_2_3 = nueva_carga(mesa_categoria_1_2, fiscal_3, [30, 20, 10]) mesa_categoria_2_1 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_1).first() carga_2_1_2 = nueva_carga(mesa_categoria_2_1, fiscal_2, [30, 20, 10]) carga_2_1_3 = nueva_carga(mesa_categoria_2_1, fiscal_3, [30, 20, 10]) mesa_categoria_2_2 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_2).first() carga_2_2_1 = nueva_carga(mesa_categoria_2_2, fiscal_1, [30, 20, 10]) carga_2_2_4 = nueva_carga(mesa_categoria_2_2, fiscal_4, [30, 20, 10]) mesa_categoria_3_1 = MesaCategoria.objects.filter( mesa=mesa_3, categoria=categoria_1).first() carga_3_1_2 = nueva_carga(mesa_categoria_3_1, fiscal_2, [30, 20, 10]) carga_3_1_4 = nueva_carga(mesa_categoria_3_1, fiscal_4, [30, 20, 10]) assert Identificacion.objects.filter(invalidada=True).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 assert Identificacion.objects.filter(fiscal=fiscal_1).count() == 2 assert Carga.objects.filter(fiscal=fiscal_1).count() == 3 # hacemos una marca explicita de troll, tienen que quedar invalidadas las cargas e identificaciones que hizo, # y ninguna mas fiscal_1.marcar_como_troll(fiscal_4) assert Identificacion.objects.filter(invalidada=True).count() == 2 assert Carga.objects.filter(invalidada=True).count() == 3 for ident in Identificacion.objects.filter(fiscal=fiscal_1): assert ident.invalidada for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada
def test_cargar_resultados_mesa_desde_ub_con_id_de_mesa( db, fiscal_client, admin_user, django_assert_num_queries): """ Es un test desaconsejadamente largo, pero me sirvió para entender el escenario. Se hace un recorrido por la carga de dos categorías desde una UB. Cuando se llama a cargar-desde-ub, cuando va por GET, es para cargar el template carga-ub.html. Cuando se le pega con POST, va a cargar un resultado. Cuando ya no tiene más categorías para cargar, te devuelve a agregar-adjunto-ub """ categoria_1 = CategoriaFactory() categoria_2 = CategoriaFactory() mesa = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_categoria_1 = MesaCategoriaFactory(mesa=mesa, categoria=categoria_1, coeficiente_para_orden_de_carga=1) mesa_categoria_2 = MesaCategoriaFactory(mesa=mesa, categoria=categoria_2, coeficiente_para_orden_de_carga=2) opcion_1 = OpcionFactory() opcion_2 = OpcionFactory() CategoriaOpcionFactory(categoria=categoria_1, opcion=opcion_1, prioritaria=True) CategoriaOpcionFactory(categoria=categoria_1, opcion=opcion_2, prioritaria=True) CategoriaOpcionFactory(categoria=categoria_2, opcion=opcion_1, prioritaria=True) CategoriaOpcionFactory(categoria=categoria_2, opcion=opcion_2, prioritaria=True) AttachmentFactory(mesa=mesa) IdentificacionFactory( mesa=mesa, status=Identificacion.STATUS.identificada, source=Identificacion.SOURCES.csv, ) consumir_novedades_identificacion() assert MesaCategoria.objects.count() == 2 for mc in MesaCategoria.objects.all(): mc.actualizar_coeficiente_para_orden_de_carga() nombre_categoria = "Un nombre en particular" # Sin tilde que si no falla el 'in' más abajo. categoria_1.nombre = nombre_categoria categoria_1.save(update_fields=['nombre']) categoria_2.nombre = 'Otro nombre' categoria_2.save(update_fields=['nombre']) url_carga = reverse('cargar-desde-ub', kwargs={'mesa_id': mesa.id}) response = fiscal_client.get(url_carga) # Nos aseguramos que haya cargado el template específico para UB. No es una redirección. assert response.status_code == HTTPStatus.OK assert url_carga in str(response.content) # categoria1 debería aparecer primero porque su mesa categoria tiene un coeficiente_para_orden_de_carga más grande assert nombre_categoria in str(response.content) tupla_opciones_electores = [ (opcion_1.id, mesa.electores // 2, mesa.electores // 2), (opcion_2.id, mesa.electores // 2, mesa.electores // 2) ] request_data = _construir_request_data_para_carga_de_resultados( tupla_opciones_electores) with django_assert_num_queries(47): response = fiscal_client.post(url_carga, request_data) # Tiene otra categoría, por lo que debería cargar y redirigirnos nuevamente a cargar-desde-ub carga = Carga.objects.get() assert carga.tipo == Carga.TIPOS.total assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('cargar-desde-ub', kwargs={'mesa_id': mesa.id}) # Hacemos el get hacia donde nos manda el redirect. Esto hace el take. response = fiscal_client.get(response.url) # Posteamos los nuevos datos. response = fiscal_client.post(url_carga, request_data) carga.refresh_from_db() cargas = Carga.objects.all() assert len(cargas) == 2 assert carga.tipo == Carga.TIPOS.total # Me lleva a continuar con el workflow. assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('cargar-desde-ub', kwargs={'mesa_id': mesa.id}) # La mesa no tiene más categorías, nos devuelve a la pantalla de carga de adjuntos. assert response.status_code == 302 # Hacemos el get hacia donde nos manda el redirect. response = fiscal_client.get(response.url) assert response.url == reverse('agregar-adjuntos-ub')
def test_attachment_unico(db): a = AttachmentFactory() assert a.foto assert a.foto_digest with pytest.raises(IntegrityError): AttachmentFactory(foto=a.foto)
def test_data_fiscales_para_monitoreo_antitrolling(db): fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() fiscal_4 = nuevo_fiscal() fiscal_5 = nuevo_fiscal() fiscal_6 = nuevo_fiscal() fiscal_7 = nuevo_fiscal() fiscal_8 = nuevo_fiscal() attach = AttachmentFactory() mesa_1 = MesaFactory() mesa_2 = MesaFactory() mesa_3 = MesaFactory() mesa_4 = MesaFactory() mesa_5 = MesaFactory() with override_config( SCORING_MINIMO_PARA_CONSIDERAR_QUE_FISCAL_ES_TROLL=500): identi_1 = reportar_problema_attachment(attach, fiscal_1) identi_2 = identificar(attach, mesa_1, fiscal_2) identi_3 = identificar(attach, mesa_2, fiscal_3) identi_4 = identificar(attach, mesa_3, fiscal_4) identi_5 = identificar(attach, mesa_4, fiscal_5) identi_6 = identificar(attach, mesa_5, fiscal_6) aumentar_scoring_troll_identificacion(300, identi_1) aumentar_scoring_troll_identificacion(450, identi_2) aumentar_scoring_troll_identificacion(520, identi_3) aumentar_scoring_troll_identificacion(100, identi_4) aumentar_scoring_troll_identificacion(51, identi_5) aumentar_scoring_troll_identificacion(30, identi_6) # sólo toma en cuenta los fiscales que ingresaron alguna vez for fiscal in [ fiscal_1, fiscal_2, fiscal_3, fiscal_4, fiscal_5, fiscal_6, fiscal_7, fiscal_8 ]: fiscal.marcar_ingreso_alguna_vez() fiscal.refresh_from_db() ParametrosAntitrolling.reset() rango_80 = FiscalesEnRangoScoringTroll().setRangoPorcentajes( 80, None).set_umbrales_de_peligro(5, 7, 10) assert rango_80.cantidad_fiscales() == 1 assert rango_80.porcentaje_fiscales() == 12.5 assert rango_80.desde_scoring == 401 assert rango_80.hasta_scoring == None assert rango_80.indicador_peligro( ) == IndicadorDePeligro.indicador_rojo rango_intermedio = FiscalesEnRangoScoringTroll().setRangoPorcentajes( 30, 60).set_umbrales_de_peligro(30, 40, 50) assert rango_intermedio.cantidad_fiscales() == 1 assert rango_intermedio.porcentaje_fiscales() == 12.5 assert rango_intermedio.desde_scoring == 151 assert rango_intermedio.hasta_scoring == 300 assert rango_intermedio.indicador_peligro( ) == IndicadorDePeligro.indicador_verde rango_amplio = FiscalesEnRangoScoringTroll().setRangoPorcentajes( 10, 60).set_umbrales_de_peligro(30, 40, 50) assert rango_amplio.cantidad_fiscales() == 3 assert rango_amplio.porcentaje_fiscales() == 37.5 assert rango_amplio.desde_scoring == 51 assert rango_amplio.hasta_scoring == 300 assert rango_amplio.indicador_peligro( ) == IndicadorDePeligro.indicador_amarillo data_troll = FiscalesTroll().set_umbrales_de_peligro(5, 10, 15) assert data_troll.cantidad_fiscales() == 1 assert data_troll.porcentaje_fiscales() == 12.5 assert data_troll.indicador_peligro( ) == IndicadorDePeligro.indicador_naranja attach_2 = AttachmentFactory() identi_2_2 = identificar(attach, mesa_1, fiscal_2) aumentar_scoring_troll_identificacion(120, identi_2_2) data_troll = FiscalesTroll().set_umbrales_de_peligro(5, 10, 15) assert data_troll.cantidad_fiscales() == 2 assert data_troll.porcentaje_fiscales() == 25 assert data_troll.indicador_peligro( ) == IndicadorDePeligro.indicador_rojo data_no_troll = FiscalesNoTroll(data_troll) assert data_no_troll.cantidad_fiscales() == 6 assert data_no_troll.porcentaje_fiscales() == 75
def test_priorizadas_ordena_por_cant_asignaciones_realizadas(db, settings): a1 = AttachmentFactory() a2 = AttachmentFactory() a3 = AttachmentFactory() assert a1.id < a2.id assert a2.id < a3.id assert set(Attachment.objects.sin_identificar()) == {a1, a2, a3} for i in range(settings.MIN_COINCIDENCIAS_IDENTIFICACION): a1.asignar_a_fiscal() a2.asignar_a_fiscal() a3.asignar_a_fiscal() # Prima el orden por id. assert list( Attachment.objects.sin_identificar().priorizadas()) == [a1, a2, a3] # Ahora a2 es devuelto. for i in range(settings.MIN_COINCIDENCIAS_IDENTIFICACION): a2.desasignar_a_fiscal() assert list( Attachment.objects.sin_identificar().priorizadas()) == [a2, a1, a3] # a2 es asignado nuevamente. for i in range(settings.MIN_COINCIDENCIAS_IDENTIFICACION): a2.asignar_a_fiscal() # Si bien a3 y a2 tienen la misma cantidad de asignaciones # vigentes, a2 fue asignado más veces. a1 y a3 empatan, salvo por id. assert list( Attachment.objects.sin_identificar().priorizadas()) == [a1, a3, a2] assert a1.cant_fiscales_asignados == a3.cant_fiscales_asignados assert a3.cant_fiscales_asignados == a2.cant_fiscales_asignados assert a3.cant_asignaciones_realizadas < a2.cant_asignaciones_realizadas
def test_identificaciones_troll(db, settings): """ Se verifica que luego de que un fiscal es detectado como troll, el estado asociado a las identificaciones que hubiera hecho cambia tal cual se espera. """ settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() fiscal_4 = nuevo_fiscal() fiscal_5 = nuevo_fiscal() categoria_1 = nueva_categoria(["o1", "o2", "o3"]) mesa_1 = MesaFactory(categorias=[categoria_1]) mesa_2 = MesaFactory(categorias=[categoria_1]) mesa_3 = MesaFactory(categorias=[categoria_1]) mesa_4 = MesaFactory(categorias=[categoria_1]) mesa_categoria_1 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_1).first() mesa_categoria_2 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_1).first() attach_1 = AttachmentFactory() attach_2 = AttachmentFactory() attach_3 = AttachmentFactory() attach_4 = AttachmentFactory() def refrescar_data(): for db_object in [ mesa_categoria_1, mesa_categoria_2, attach_1, attach_2, attach_3, attach_4, fiscal_1, fiscal_2, fiscal_3, fiscal_4, fiscal_5 ]: db_object.refresh_from_db() with override_config( SCORING_MINIMO_PARA_CONSIDERAR_QUE_FISCAL_ES_TROLL=50, SCORING_TROLL_IDENTIFICACION_DISTINTA_A_CONFIRMADA=180): identificar(attach_1, mesa_1, fiscal_1) identificar(attach_1, mesa_1, fiscal_2) identificar(attach_2, mesa_2, fiscal_2) identificar(attach_2, mesa_2, fiscal_3) identificar(attach_3, mesa_1, fiscal_1) identificar(attach_3, mesa_4, fiscal_3) identificar(attach_4, mesa_1, fiscal_1) identificar(attach_4, mesa_4, fiscal_2) nueva_carga(mesa_categoria_1, fiscal_3, [20, 25, 15]) nueva_carga(mesa_categoria_1, fiscal_4, [20, 25, 15]) nueva_carga(mesa_categoria_2, fiscal_4, [60, 25, 20]) nueva_carga(mesa_categoria_2, fiscal_5, [60, 25, 20]) assert Identificacion.objects.filter(procesada=False).count() == 8 assert Identificacion.objects.filter(invalidada=True).count() == 0 assert Carga.objects.filter(procesada=False).count() == 4 assert Carga.objects.filter(invalidada=True).count() == 0 # hasta aca: a1, a2 identificada; a3, a4 sin identificar. consumir_novedades_identificacion() consumir_novedades_carga() refrescar_data() assert attach_1.status == Attachment.STATUS.identificada assert attach_2.status == Attachment.STATUS.identificada assert attach_3.status == Attachment.STATUS.sin_identificar assert attach_4.status == Attachment.STATUS.sin_identificar assert mesa_categoria_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1.carga_testigo is not None assert mesa_categoria_1.coeficiente_para_orden_de_carga is not None assert mesa_categoria_2.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2.carga_testigo is not None assert mesa_categoria_2.coeficiente_para_orden_de_carga is not None assert not fiscal_1.troll assert Identificacion.objects.filter(procesada=False).count() == 0 assert Identificacion.objects.filter(invalidada=True).count() == 0 assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 identificar(attach_4, mesa_4, fiscal_4) # al consolidar esta identificacion, el fiscal 1 pasa a ser troll # las identificaciones del fiscal 1 se invalidan consumir_novedades_identificacion() refrescar_data() assert attach_1.status == Attachment.STATUS.identificada assert attach_2.status == Attachment.STATUS.identificada assert attach_3.status == Attachment.STATUS.sin_identificar assert attach_4.status == Attachment.STATUS.identificada assert mesa_categoria_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1.carga_testigo is not None assert mesa_categoria_1.coeficiente_para_orden_de_carga is not None assert mesa_categoria_2.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2.carga_testigo is not None assert mesa_categoria_2.coeficiente_para_orden_de_carga is not None assert fiscal_1.troll assert Identificacion.objects.filter(procesada=False).count() == 3 assert Identificacion.objects.filter(invalidada=True).count() == 3 for ident in Identificacion.objects.filter(fiscal=fiscal_1): assert ident.invalidada assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 # se corre otra consolidacion de identificaciones # a1 pasa a sin_identificar, se invalidan las cargas de m1 y se le borra el orden de carga consumir_novedades_identificacion() refrescar_data() assert attach_1.status == Attachment.STATUS.sin_identificar assert attach_2.status == Attachment.STATUS.identificada assert attach_3.status == Attachment.STATUS.sin_identificar assert attach_4.status == Attachment.STATUS.identificada assert mesa_categoria_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1.carga_testigo is not None assert mesa_categoria_1.coeficiente_para_orden_de_carga is None assert mesa_categoria_2.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2.carga_testigo is not None assert mesa_categoria_2.coeficiente_para_orden_de_carga is not None assert fiscal_1.troll assert Identificacion.objects.filter(procesada=False).count() == 0 assert Identificacion.objects.filter(invalidada=True).count() == 3 assert Carga.objects.filter(procesada=False).count() == 2 assert Carga.objects.filter(invalidada=True).count() == 2 for carga in Carga.objects.filter(mesa_categoria=mesa_categoria_1): assert carga.invalidada # finalmente, se ejecuta una consolidacion de cargas # la MesaCategoria de m1 pasa a sin_cargas, y se le borra la carga testigo consumir_novedades_carga() refrescar_data() assert mesa_categoria_1.status == MesaCategoria.STATUS.sin_cargar assert mesa_categoria_1.carga_testigo is None assert mesa_categoria_1.coeficiente_para_orden_de_carga is None assert mesa_categoria_2.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2.carga_testigo is not None assert mesa_categoria_2.coeficiente_para_orden_de_carga is not None assert fiscal_1.troll assert Identificacion.objects.filter(procesada=False).count() == 0 assert Identificacion.objects.filter(invalidada=True).count() == 3 assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 2 for carga in Carga.objects.filter(mesa_categoria=mesa_categoria_1): assert carga.invalidada
def test_siguiente_happy_path_parcial_y_total_con_modo_ub( db, fiscal_client, admin_user, settings): # Este test no es del todo realista porque se lo ejecuta con la cantidad de cargas/identificaciones # necesarias para consolidar en 1, pero al menos prueba que se siga el circuito con modo_ub=True. settings.MIN_COINCIDENCIAS_CARGAS = 1 settings.MIN_COINCIDENCIAS_IDENTIFICACION = 1 modo_ub_querry_string = '?modo_ub=True' mesa = MesaFactory() from adjuntos.models import PreIdentificacion from scheduling.models import ColaCargasPendientes p = PreIdentificacion(fiscal=admin_user.fiscal, distrito=mesa.circuito.seccion.distrito) p.save() a = AttachmentFactory(status='sin_identificar', pre_identificacion=p) scheduler() assert ColaCargasPendientes.largo_cola() == 1 response = fiscal_client.get( reverse('siguiente-accion') + modo_ub_querry_string) assert response.status_code == HTTPStatus.FOUND # Me manda a idenficarlas con modo_ub assert response.url == reverse('asignar-mesa', args=[a.id]) + modo_ub_querry_string assert ColaCargasPendientes.largo_cola() == 0 # La identifico. a.mesa = mesa a.status = 'identificada' a.save() mc1 = MesaCategoriaFactory(categoria__requiere_cargas_parciales=True, coeficiente_para_orden_de_carga=1, mesa=mesa) scheduler() assert ColaCargasPendientes.largo_cola() == 1 response = fiscal_client.get( reverse('siguiente-accion') + modo_ub_querry_string) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-parcial', args=[mc1.id]) + modo_ub_querry_string carga = CargaFactory(mesa_categoria=mc1, tipo='parcial', origen='csv') consumir_novedades_carga() scheduler() mc1.refresh_from_db() assert mc1.status == MesaCategoria.STATUS.parcial_consolidada_dc # Porque la cant de cargas está en 1. assert mc1.carga_testigo == carga mc1.desasignar_a_fiscal() response = fiscal_client.get( reverse('siguiente-accion') + modo_ub_querry_string) assert response.url == reverse('carga-total', args=[mc1.id]) + modo_ub_querry_string carga = CargaFactory(mesa_categoria=mc1, tipo='total', origen='csv') consumir_novedades_carga() scheduler() mc1.refresh_from_db() assert mc1.status == MesaCategoria.STATUS.total_consolidada_dc # Porque la cant de cargas está en 1. assert mc1.carga_testigo == carga response = fiscal_client.get( reverse('siguiente-accion') + modo_ub_querry_string) # No hay actas para cargar, vuelta a empezar. assert response.status_code == HTTPStatus.OK assert 'No hay actas para cargar' in str(response.content)
def identificar_mesa(mesa, fiscal): attach = AttachmentFactory() identificar(attach, mesa, fiscal) consolidar_identificaciones(attach)