def test_troll_parcial_dc_a_sin_consolidar(db, settings): with override_config( SCORING_MINIMO_PARA_CONSIDERAR_QUE_FISCAL_ES_TROLL=20): 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() 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 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 assert Carga.objects.filter(invalidada=True).count() == 0 aplicar_marca_troll(fiscal_2) consumir_novedades_carga() refrescar_data([mesa_categoria_1, fiscal_2]) assert mesa_categoria_1.status == MesaCategoria.STATUS.parcial_sin_consolidar assert Carga.objects.filter(invalidada=True).count() == 1
def test_siguiente_happy_path_parcial_y_total_con_scheduler( db, fiscal_client, settings): settings.MIN_COINCIDENCIAS_CARGAS = 1 mesa = MesaFactory() a = AttachmentFactory(mesa=mesa, status='identificada') mc1 = MesaCategoriaFactory(categoria__requiere_cargas_parciales=True, coeficiente_para_orden_de_carga=1, mesa=mesa) scheduler() response = fiscal_client.get(reverse('siguiente-accion')) assert response.status_code == HTTPStatus.FOUND assert response.url == reverse('carga-parcial', args=[mc1.id]) carga = CargaFactory(mesa_categoria=mc1, tipo='parcial') consumir_novedades_carga() scheduler() mc1.refresh_from_db() assert mc1.status == MesaCategoria.STATUS.parcial_consolidada_dc assert mc1.carga_testigo == carga mc1.desasignar_a_fiscal() response = fiscal_client.get(reverse('siguiente-accion')) assert response.url == reverse('carga-total', args=[mc1.id]) carga = CargaFactory(mesa_categoria=mc1, tipo='total') consumir_novedades_carga() scheduler() mc1.refresh_from_db() assert mc1.status == MesaCategoria.STATUS.total_consolidada_dc assert mc1.carga_testigo == carga response = fiscal_client.get(reverse('siguiente-accion')) # 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 test_formset_en_carga_total_reusa_parcial_confirmada( db, fiscal_client, admin_user, settings): # Solo una carga, para simplificar el setup settings.MIN_COINCIDENCIAS_CARGAS = 1 c = CategoriaFactory(id=25000, opciones=[]) # Notar que el orden no coincide con el id o1 = CategoriaOpcionFactory(categoria=c, orden=3, prioritaria=True).opcion o2 = CategoriaOpcionFactory(categoria=c, orden=1, prioritaria=False).opcion o3 = CategoriaOpcionFactory(categoria=c, orden=2, prioritaria=False).opcion o4 = CategoriaOpcionFactory(categoria=c, orden=4, prioritaria=True).opcion mc = MesaCategoriaFactory(categoria=c) mc.asignar_a_fiscal() admin_user.fiscal.asignar_mesa_categoria(mc) # Se carga parcialente, la opcion prioritaira "o" carga = CargaFactory(mesa_categoria=mc, tipo='parcial') VotoMesaReportadoFactory(carga=carga, opcion=o1, votos=10) VotoMesaReportadoFactory(carga=carga, opcion=o4, votos=3) # Consolidamos. consumir_novedades_carga() mc.refresh_from_db() assert mc.status == MesaCategoria.STATUS.parcial_consolidada_dc assert mc.carga_testigo == carga assert set(carga.opcion_votos()) == {(o1.id, 10), (o4.id, 3)} # Ahora pedimos la carga total totales = reverse('carga-total', args=[mc.id]) response = fiscal_client.get(totales) # Tenemos las tres opciones en orden assert len(response.context['formset']) == 4 + len( Opcion.opciones_no_partidarias_obligatorias()) assert response.context['formset'][0].initial['opcion'] == o2 assert response.context['formset'][1].initial['opcion'] == o3 assert response.context['formset'][2].initial['opcion'] == o1 assert response.context['formset'][3].initial['opcion'] == o4 # y los valores de los votos assert response.context['formset'][0].initial['votos'] is None assert response.context['formset'][1].initial['votos'] is None assert response.context['formset'][2].initial['votos'] == 10 assert response.context['formset'][3].initial['votos'] == 3 # el valor previo es readonly assert response.context['formset'][2].fields['votos'].widget.attrs[ 'readonly'] is True assert response.context['formset'][3].fields['votos'].widget.attrs[ 'readonly'] is True
def test_avance_de_carga_identificacion_parcial(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 5 mesas, parcialmente 2 más attachs = AttachmentFactory.create_batch(30) for ix in range(5): identificar(attachs[ix], mesas_1[ix], fiscal_1) identificar(attachs[ix], mesas_1[ix], fiscal_2) identificar(attachs[5], mesas_1[5], fiscal_1) identificar(attachs[6], mesas_1[6], 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) 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(), 3, 540, 30, 37.24) verificar_resultado(resultados.sin_identificar_con_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.en_identificacion_sin_cargas(), 2, 310, 20, 21.38) verificar_resultado(resultados.en_identificacion_con_cargas(), 0, 0, 0, 0) verificar_resultado(resultados.sin_cargar(), 3, 390, 30, 26.9) 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(), 0, 0, 0, 0) verificar_resultado(resultados.carga_total_consolidada_dc(), 0, 0, 0, 0)
def test_consumir_novedades_carga_tres_ok_tres_error(db, settings): # En esta variable se almacena el comportamiento que tendrá cada llamado a # la función consolidar_cargas para cada mesa_categoria a procesar. # Las mc1, mc3 y mc5 se procesarán con normalidad y sus cargas c1, c3 y c6 # quedarán marcadas como procesadas=True. # Para las mc2 y mc4 se lanzará una Exception y sus cargas c2, c4 y c5 # quedarán como procesada=False. side_effects = [ mock.DEFAULT, #comportamiento para mc1 Exception('error'), #comportamiento para mc2 mock.DEFAULT, #comportamiento para mc3 Exception('error'), #comportamiento para mc4 mock.DEFAULT #comportamiento para mc5 ] with mock.patch('adjuntos.consolidacion.consolidar_cargas', side_effect=side_effects): m1 = MesaFactory() m2 = MesaFactory() mc1 = MesaCategoriaFactory(mesa=m1) mc2 = MesaCategoriaFactory(mesa=m1) mc3 = MesaCategoriaFactory(mesa=m2) mc4 = MesaCategoriaFactory(mesa=m2) mc5 = MesaCategoriaFactory(mesa=m2) c1 = CargaFactory(mesa_categoria=mc1, tipo='parcial') c2 = CargaFactory(mesa_categoria=mc2, tipo='total') c3 = CargaFactory(mesa_categoria=mc3, tipo='total') c4 = CargaFactory(mesa_categoria=mc4, tipo='total') c5 = CargaFactory(mesa_categoria=mc4, tipo='parcial') c6 = CargaFactory(mesa_categoria=mc5, tipo='total') consumir_novedades_carga() # Chequeamos que las no procesadas son 3 no_procesadas = Carga.objects.filter(procesada=False) assert no_procesadas.count() == 3 # Chequeamos que las no procesadas son c2, c4 y c5 no_procesadas_ids = map(lambda x: x.id, no_procesadas) assert set([c2.id, c4.id, c5.id]) == set(no_procesadas_ids) # Chequeamos que las procesadas son 3 procesadas = Carga.objects.filter(procesada=True) assert procesadas.count() == 3 # # Chequeamos que las procesadas son c1, c3 y c6 procesadas_ids = map(lambda x: x.id, procesadas) assert set([c1.id, c3.id, c6.id]) == set(procesadas_ids)
def test_avance_de_carga_sencillo(db, settings): # settings settings.MIN_COINCIDENCIAS_IDENTIFICACION = 2 settings.MIN_COINCIDENCIAS_CARGA = 2 # categoria con cuatro opciones, dos prioritarias, dos no prioritarias pv = 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], 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() # a siete mesas les hago identificación total, a una identificación parcial attachs = AttachmentFactory.create_batch(10) for ix in range(7): identificar(attachs[ix], mesas[ix], fiscal_1) identificar(attachs[ix], mesas[ix], fiscal_2) identificar(attachs[7], mesas[7], fiscal_1) consumir_novedades_identificacion() # primer carga parcial en tres mesas for ix in range(3): nueva_carga(mesacat(mesas[ix], pv), fiscal_1, [50, 30], Carga.TIPOS.parcial) # a una de estas tres le mando una segunda carga coincidente nueva_carga(mesacat(mesas[0], pv), fiscal_2, [50, 30], Carga.TIPOS.parcial) consumir_novedades_carga() # estamos para probar vorwaerts = AvanceDeCarga() resultados = vorwaerts.get_resultados(pv) verificar_resultado(resultados.total(), 10, 1450, 100, 100) verificar_resultado(resultados.sin_identificar_sin_cargas(), 2, 370, 20, 25.52) verificar_resultado(resultados.en_identificacion_sin_cargas(), 1, 170, 10, 11.72) verificar_resultado(resultados.carga_parcial_sin_consolidar(), 2, 230, 20, 15.86) verificar_resultado(resultados.carga_parcial_consolidada_dc(), 1, 100, 10, 6.9) verificar_resultado(resultados.carga_total_sin_consolidar(), 0, 0, 0, 0) verificar_resultado(resultados.carga_total_consolidada_dc(), 0, 0, 0, 0)
def test_metadata_de_mesa(db, settings): settings.MIN_COINCIDENCIAS_CARGAS = 1 o1 = OpcionFactory(tipo=Opcion.TIPOS.metadata) o2 = OpcionFactory(tipo=Opcion.TIPOS.metadata) o3 = OpcionFactory() # opcion comun # 2 categorias c1 = CategoriaFactory(opciones=[o1, o3]) c2 = CategoriaFactory(opciones=[o1, o2, o3]) # misma mesa mc1 = MesaCategoriaFactory(categoria=c1) mesa = mc1.mesa mc2 = MesaCategoriaFactory(categoria=c2, mesa=mesa) # carga categoria 1 carga1 = CargaFactory(mesa_categoria=mc1, tipo='total') VotoMesaReportadoFactory(carga=carga1, opcion=o1, votos=10) VotoMesaReportadoFactory(carga=carga1, opcion=o3, votos=54) # como aun no hay cargas consolidadas, no hay metadata assert set(mesa.metadata()) == set() consumir_novedades_carga() # una vez consolidada, la mesa ya tiene metadatos accesibles mc1.refresh_from_db() assert mc1.status == MesaCategoria.STATUS.total_consolidada_dc assert set(mesa.metadata()) == {(o1.id, 10)} # carga 2 para otra categoria. tiene una metadata extra carga2 = CargaFactory(mesa_categoria=mc2, tipo='total') VotoMesaReportadoFactory(carga=carga2, opcion=o1, votos=10) VotoMesaReportadoFactory(carga=carga2, opcion=o2, votos=0) VotoMesaReportadoFactory(carga=carga2, opcion=o3, votos=54) consumir_novedades_carga() assert set(mesa.metadata()) == {(o1.id, 10), (o2.id, 0)} # reportes de metadata a otra mesa no afectan VotoMesaReportadoFactory( carga__mesa_categoria__status=MesaCategoria.STATUS.total_consolidada_dc, opcion=o1, votos=14 ) assert set(mesa.metadata()) == {(o1.id, 10), (o2.id, 0)}
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_troll_total_consolidada_dc_a_parcial_sin_consolidar(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() 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]) 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]) nueva_carga(mesa_categoria_1, fiscal_2, [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_2) consumir_novedades_carga() refrescar_data([mesa_categoria_1, fiscal_2]) assert mesa_categoria_1.status == MesaCategoria.STATUS.parcial_sin_consolidar assert Carga.objects.filter(invalidada=True).count() == 3
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 consumir_novedades_y_actualizar_objetos(lista=None): consumir_novedades_carga() if not lista: return for item in lista: item.refresh_from_db()
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_cargas_troll_con_problemas(db, settings): """ Se verifica que luego de que un fiscal es detectado como troll, el estado de las cargas "con problemas" en las que participó cambie adecuadamente """ settings.MIN_COINCIDENCIAS_CARGAS = 2 settings.MIN_COINCIDENCIAS_CARGAS_PROBLEMA = 2 fiscal_1 = nuevo_fiscal() fiscal_2 = nuevo_fiscal() fiscal_3 = nuevo_fiscal() categoria_1 = nueva_categoria(["o1", "o2", "o3"]) mesa_1 = MesaFactory(categorias=[categoria_1]) mesa_2 = MesaFactory(categorias=[categoria_1]) mesa_categoria_1_1 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_1).first() mesa_categoria_2_1 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_1).first() carga_1_1_1 = nueva_carga(mesa_categoria_1_1, fiscal_1, [20, 25, 15]) carga_1_1_2 = reportar_problema_mesa_categoria(mesa_categoria_1_1, fiscal_2) carga_2_1_1 = reportar_problema_mesa_categoria(mesa_categoria_2_1, fiscal_1) carga_2_1_3 = nueva_carga(mesa_categoria_2_1, fiscal_3, [60, 30, 15]) def refrescar_data(): for db_object in [ mesa_categoria_1_1, mesa_categoria_2_1, fiscal_1, fiscal_2, fiscal_3 ]: db_object.refresh_from_db() assert Carga.objects.filter(procesada=False).count() == 4 assert Carga.objects.filter(invalidada=True).count() == 0 assert not fiscal_1.troll # hasta aca: (1,1) y (2,1) sin consolidar, tienen problemas pero no la cantidad necesaria consumir_novedades_carga() refrescar_data() assert mesa_categoria_1_1.status == MesaCategoria.STATUS.total_sin_consolidar assert mesa_categoria_2_1.status == MesaCategoria.STATUS.total_sin_consolidar assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 # ahora digo de prepo que el fiscal 1 es troll # Por lo tanto sus cargas pasan a invalidadas y pendientes de proceso fiscal_1.marcar_como_troll(fiscal_3) assert fiscal_1.troll assert Carga.objects.filter(invalidada=True).count() == 2 assert Carga.objects.filter(procesada=False).count() == 2 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada and not carga.procesada # ahora lanzo una nueva consolidacion, que deberia procesar las cargas invalidadas # La (1,1) queda sin_cargar, porque la única carga válida es un problema # La (2,1) sigue sin_consolidar consumir_novedades_carga() refrescar_data() assert mesa_categoria_1_1.status == MesaCategoria.STATUS.sin_cargar assert mesa_categoria_2_1.status == MesaCategoria.STATUS.total_sin_consolidar assert Carga.objects.filter(invalidada=True).count() == 2 assert Carga.objects.filter(procesada=False).count() == 0 assert mesa_categoria_2_1.carga_testigo == carga_2_1_3 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada
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_cargas_troll_no_consolidadas(db, settings): """ Se verifica que luego de que un fiscal es detectado como troll, el estado de las cargas "en conflicto" o "sin consolidar" en las que participó cambie adecuadamente """ settings.MIN_COINCIDENCIAS_CARGAS = 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"]) categoria_2 = nueva_categoria(["p1", "p2", "p3", "p4"]) mesa_1 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_2 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_3 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_4 = MesaFactory(categorias=[categoria_1]) mesa_categoria_1_1 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_1).first() mesa_categoria_1_2 = MesaCategoria.objects.filter( mesa=mesa_1, categoria=categoria_2).first() mesa_categoria_2_1 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_1).first() mesa_categoria_2_2 = MesaCategoria.objects.filter( mesa=mesa_2, categoria=categoria_2).first() mesa_categoria_3_1 = MesaCategoria.objects.filter( mesa=mesa_3, categoria=categoria_1).first() mesa_categoria_3_2 = MesaCategoria.objects.filter( mesa=mesa_3, categoria=categoria_2).first() mesa_categoria_4_1 = MesaCategoria.objects.filter( mesa=mesa_4, categoria=categoria_1).first() carga_1_1_1 = nueva_carga(mesa_categoria_1_1, fiscal_1, [20, 25, 15]) # 20 de diferencia carga_1_1_2 = nueva_carga(mesa_categoria_1_1, fiscal_2, [30, 20, 10]) carga_1_1_3 = nueva_carga(mesa_categoria_1_1, fiscal_3, [30, 20, 10]) carga_1_2_1 = nueva_carga(mesa_categoria_1_2, fiscal_1, [30, 15, 15, 10]) carga_1_2_3 = nueva_carga(mesa_categoria_1_2, fiscal_3, [30, 15, 10, 5]) carga_1_2_4 = nueva_carga(mesa_categoria_1_2, fiscal_4, [30, 18, 7, 5]) carga_2_1_2 = nueva_carga(mesa_categoria_2_1, fiscal_2, [60, 25, 20]) carga_2_1_4 = nueva_carga(mesa_categoria_2_1, fiscal_4, [60, 30, 15]) carga_2_2_1 = nueva_carga(mesa_categoria_2_2, fiscal_1, [60, 20, 18, 7]) # 40 de diferencia carga_2_2_4 = nueva_carga(mesa_categoria_2_2, fiscal_4, [40, 30, 25, 10]) carga_3_1_1 = nueva_carga(mesa_categoria_3_1, fiscal_1, [25, 15, 20]) carga_3_1_5 = nueva_carga(mesa_categoria_3_1, fiscal_5, [28, 12, 20]) carga_3_2_1 = nueva_carga(mesa_categoria_3_2, fiscal_1, [60, 20, 18, 7]) carga_4_1_2 = nueva_carga(mesa_categoria_4_1, fiscal_2, [60, 25, 20]) def refrescar_data(): for mesa_categoria in [ mesa_categoria_1_1, mesa_categoria_1_2, mesa_categoria_2_1, mesa_categoria_2_2, mesa_categoria_3_1, mesa_categoria_3_2, mesa_categoria_4_1 ]: mesa_categoria.refresh_from_db() for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4, fiscal_5]: fiscal.refresh_from_db() with override_config( SCORING_MINIMO_PARA_CONSIDERAR_QUE_FISCAL_ES_TROLL=50): assert Carga.objects.filter(procesada=False).count() == 14 assert Carga.objects.filter(invalidada=True).count() == 0 assert not fiscal_1.troll # hasta aca: (1,1) consolidada; (3,2) y (4,1) sin consolidar; (1,2), (2,1), (2,2), (3,1) en conflicto # fiscal_1 tiene 20 de scoring troll consumir_novedades_carga() refrescar_data() assert mesa_categoria_1_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1_2.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_2_1.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_3_1.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_3_2.status == MesaCategoria.STATUS.total_sin_consolidar assert mesa_categoria_4_1.status == MesaCategoria.STATUS.total_sin_consolidar assert fiscal_1.scoring_troll() == 20 assert not fiscal_1.troll assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 # ahora hago una carga que confirma la MC (2,2). Esto tiene que desencadenar que # - el fiscal 1 se detecta como troll # - sus cargas pasan a invalidadas y pendientes de proceso carga_2_2_5 = nueva_carga(mesa_categoria_2_2, fiscal_5, [40, 30, 25, 10]) assert Carga.objects.filter(procesada=False).count() == 1 consumir_novedades_carga() refrescar_data() assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_consolidada_dc assert fiscal_1.troll assert fiscal_1.scoring_troll() == 60 assert Carga.objects.filter(invalidada=True).count() == 5 assert Carga.objects.filter(procesada=False).count() == 5 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada and not carga.procesada # ahora lanzo una nueva consolidacion, que deberia procesar las cargas invalidadas # me fijo que el estado de cada MC quede como lo espero # cambian (3,1) y (3,2). # La (1,1) y la (2,2) no dependen de la carga del troll para quedar confirmadas # En (1,2) sigue estando en conflicto # En (2,1) y en (4,1) y no participo el troll consumir_novedades_carga() refrescar_data() assert mesa_categoria_1_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1_2.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_2_1.status == MesaCategoria.STATUS.total_en_conflicto assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_3_1.status == MesaCategoria.STATUS.total_sin_consolidar assert mesa_categoria_3_2.status == MesaCategoria.STATUS.sin_cargar assert mesa_categoria_4_1.status == MesaCategoria.STATUS.total_sin_consolidar assert Carga.objects.filter(invalidada=True).count() == 5 assert Carga.objects.filter(procesada=False).count() == 0 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada
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 test_carga_confirmada_troll_vuelve_a_sin_consolidar(db, settings): """ Se verifica que luego de que un fiscal que habia hecho una carga aceptada es detectado como troll, y que posteriormente se ejecuta una consolidacion de cargas, el estado de la MesaCategoria donde participo el troll vuelve a "sin consolidar" """ settings.MIN_COINCIDENCIAS_CARGAS = 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"]) categoria_2 = nueva_categoria(["p1", "p2", "p3", "p4"]) mesa_1 = MesaFactory(categorias=[categoria_1, categoria_2]) mesa_2 = MesaFactory(categorias=[categoria_1, categoria_2]) 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, [20, 25, 15]) # 20 de diferencia carga_1_1_2 = nueva_carga(mesa_categoria_1_1, fiscal_2, [30, 20, 10]) carga_1_1_3 = nueva_carga(mesa_categoria_1_1, fiscal_3, [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, 15, 10, 5]) carga_1_2_3 = nueva_carga(mesa_categoria_1_2, fiscal_3, [30, 15, 10, 5]) 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, [60, 30, 15]) carga_2_1_4 = nueva_carga(mesa_categoria_2_1, fiscal_4, [60, 30, 15]) 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, [75, 10, 18, 7]) # 80 de diferencia carga_2_2_4 = nueva_carga(mesa_categoria_2_2, fiscal_4, [35, 30, 35, 10]) def refrescar_data(): for mesa_categoria in [ mesa_categoria_1_1, mesa_categoria_1_2, mesa_categoria_2_1, mesa_categoria_2_2 ]: mesa_categoria.refresh_from_db() for fiscal in [fiscal_1, fiscal_2, fiscal_3, fiscal_4, fiscal_5]: fiscal.refresh_from_db() with override_config(SCORING_MINIMO_PARA_CONSIDERAR_QUE_FISCAL_ES_TROLL=50, SCORING_TROLL_DESCUENTO_ACCION_CORRECTA=30): assert Carga.objects.filter(procesada=False).count() == 9 assert Carga.objects.filter(invalidada=True).count() == 0 assert not fiscal_1.troll # hasta aca: (1,1), (1,2) y (2,1) consolidadas, (2,2) en conflicto, fiscal_1 tiene -10 de scoring troll # (20 de la diferencia de (1,1), -30 porque sus valores son los aceptados en (1,2)) consumir_novedades_carga() refrescar_data() for mesa_categoria in [ mesa_categoria_1_1, mesa_categoria_1_2, mesa_categoria_2_1 ]: assert mesa_categoria.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_en_conflicto assert fiscal_1.scoring_troll() == -10 assert not fiscal_1.troll assert Carga.objects.filter(procesada=False).count() == 0 assert Carga.objects.filter(invalidada=True).count() == 0 # ahora hago una carga que confirma la MC (2,2). Esto tiene que desencadenar que # - el fiscal 1 se detecta como troll # - sus cargas pasan a invalidadas y pendientes de proceso carga_2_2_5 = nueva_carga(mesa_categoria_2_2, fiscal_5, [35, 30, 35, 10]) assert Carga.objects.filter(procesada=False).count() == 1 consumir_novedades_carga() refrescar_data() assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_consolidada_dc assert fiscal_1.troll assert fiscal_1.scoring_troll() == 70 assert Carga.objects.filter(invalidada=True).count() == 3 assert Carga.objects.filter(procesada=False).count() == 3 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada and not carga.procesada # ahora lanzo una nueva consolidacion, que deberia procesar las cargas invalidadas # me fijo que el estado de cada MC quede como lo espero # la unica que cambio es la (1,2). # La (1,1) y la (2,2) no dependen de la carga del troll para quedar confirmadas # En la (2,1) no participo el troll consumir_novedades_carga() refrescar_data() assert mesa_categoria_1_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_1_2.status == MesaCategoria.STATUS.total_sin_consolidar assert mesa_categoria_2_1.status == MesaCategoria.STATUS.total_consolidada_dc assert mesa_categoria_2_2.status == MesaCategoria.STATUS.total_consolidada_dc assert Carga.objects.filter(invalidada=True).count() == 3 assert Carga.objects.filter(procesada=False).count() == 0 for carga in Carga.objects.filter(fiscal=fiscal_1): assert carga.invalidada