예제 #1
0
def test_siguiente_prioriza_categoria(db, settings):
    f = FiscalFactory()
    c = CategoriaFactory(prioridad=2)
    c2 = CategoriaFactory(prioridad=1)
    m1 = MesaFactory()
    AttachmentFactory(mesa=m1)
    mc1 = MesaCategoriaFactory(
        status=MesaCategoria.STATUS.parcial_sin_consolidar,
        categoria=c,
        mesa=m1,
    )
    mc1.actualizar_coeficiente_para_orden_de_carga()
    m2 = MesaFactory()
    AttachmentFactory(mesa=m2)
    mc2 = MesaCategoriaFactory(
        categoria=c2,
        status=MesaCategoria.STATUS.parcial_sin_consolidar,
        mesa=m2,
    )
    mc2.actualizar_coeficiente_para_orden_de_carga()
    # Se recibe la mc con categoria más prioritaria.
    assert MesaCategoria.objects.siguiente() == mc2
    for i in range(settings.MIN_COINCIDENCIAS_CARGAS):
        mc2.asignar_a_fiscal()
    # Luego la de la categoría menos prioritaria.
    assert MesaCategoria.objects.siguiente() == mc1
예제 #2
0
def test_identificadas_excluye_sin_orden(db):
    m1 = MesaFactory()
    AttachmentFactory(mesa=m1)
    mc1 = MesaCategoriaFactory(mesa=m1)
    m2 = MesaFactory()
    AttachmentFactory(mesa=m2)
    mc2 = MesaCategoriaFactory(coeficiente_para_orden_de_carga=0.1, mesa=m2)
    assert mc1.coeficiente_para_orden_de_carga is None
    assert mc1 not in MesaCategoria.objects.identificadas()
    assert mc2 in MesaCategoria.objects.identificadas()
예제 #3
0
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)
예제 #4
0
def test_efecto_diferencia_1(db, caplog):
    fiscal_1 = nuevo_fiscal()
    fiscal_2 = nuevo_fiscal()
    mesa_categoria = MesaCategoriaFactory()
    carga_1 = nueva_carga(mesa_categoria, fiscal_1, [30, 20, 10])
    carga_1.actualizar_firma()
    mesa_categoria.carga_testigo = carga_1
    mesa_categoria.save()

    # incompatible
    carga_2 = nueva_carga(mesa_categoria, fiscal_2, [30, 20, 9])
    carga_2.actualizar_firma()
    efecto_scoring_troll_confirmacion_carga(mesa_categoria)
    # hay un solo evento troll del fiscal 2, y la diferencia es 1
    assert EventoScoringTroll.objects.filter(
        fiscal_afectado=fiscal_2).get().variacion == carga_1 - carga_2 == 1
예제 #5
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)
예제 #6
0
def test_efecto_ignora_cargas_incompatibles(db, caplog):
    with override_config(SCORING_TROLL_DESCUENTO_ACCION_CORRECTA=28):
        fiscal_1 = nuevo_fiscal()
        fiscal_2 = nuevo_fiscal()
        mesa_categoria = MesaCategoriaFactory()
        carga_1 = nueva_carga(mesa_categoria, fiscal_1, [30, 20, 10])
        carga_1.actualizar_firma()
        mesa_categoria.carga_testigo = carga_1
        mesa_categoria.save()

        # incompatible
        carga_2 = nueva_carga(mesa_categoria, fiscal_2, [30, 20])
        carga_2.actualizar_firma()
        efecto_scoring_troll_confirmacion_carga(mesa_categoria)

        # se ignoran las diferencias, sólo se genera evento con variación negativa para la carga testigo
        assert EventoScoringTroll.objects.count() == 1
        assert EventoScoringTroll.objects.get().variacion == -28
예제 #7
0
def test_prioridades_mesacat_categoria_prioritaria(db, settings, proporcion, orden_de_llegada, prioridad):
    """
    Prioridades para una MesaCategoria de una seccion standard, para una categoria prioritaria,
    en un circuito de 100 mesas.
    """
    definir_prioridades_seccion_categoria(settings)

    mesa_categoria = MesaCategoriaFactory(
        categoria=categoria_pv(), mesa=mesa_en_seccion(seccion_standard()))
    prioridades = mapa_prioridades_para_mesa_categoria(mesa_categoria)

    assert(prioridades.valor_para(proporcion, orden_de_llegada)) == prioridad
예제 #8
0
def test_cargar_resultados_redirige_a_identificar(db, fiscal_client, status,
                                                  parcial):
    mesa = MesaFactory()
    a = AttachmentFactory(mesa=mesa)
    c1 = CategoriaFactory(requiere_cargas_parciales=True)
    m1c1 = MesaCategoriaFactory(categoria=c1,
                                coeficiente_para_orden_de_carga=0.1,
                                status=status,
                                mesa=mesa)
    response = fiscal_client.get(reverse('siguiente-accion'))
    assert response.status_code == HTTPStatus.FOUND
    assert response.url.startswith('/clasificar-actas/')
예제 #9
0
 def agregar_mesacats(self, settings):
     opciones_prioritarias = ["FT", "JC"]
     opciones_no_prioritarias = ["CF", "FIT", "Desp"]
     # presidente
     categoria_pv = nueva_categoria(
         settings.SLUG_CATEGORIA_PRESI_Y_VICE, opciones_prioritarias, opciones_no_prioritarias)
     self.mesacats_pv_pba = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_pv) for mesa in self.mesas_pba]
     self.mesacats_pv_caba = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_pv) for mesa in self.mesas_caba]
     self.mesacats_pv_cat = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_pv) for mesa in self.mesas_cat]
     # gobernador PBA
     categoria_gv_pba = nueva_categoria(
         settings.SLUG_CATEGORIA_GOB_Y_VICE_PBA, opciones_prioritarias, opciones_no_prioritarias, self.distrito_pba)
     self.mesacats_gv_pba = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_gv_pba) for mesa in self.mesas_pba]
     # una categoría CABA
     categoria_jefe_de_gobierno_caba = nueva_categoria(
         "JG_CABA", opciones_prioritarias, opciones_no_prioritarias, self.distrito_caba)
     self.mesacats_jg_caba = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_jefe_de_gobierno_caba) for mesa in self.mesas_caba]
     # una categoría Catamarca
     categoria_diputados_catamarca = nueva_categoria(
         "DIP_CAT", opciones_prioritarias, opciones_no_prioritarias, self.distrito_cat)
     self.mesacats_jg_caba = [MesaCategoriaFactory(
         mesa=mesa, categoria=categoria_diputados_catamarca) for mesa in self.mesas_cat]
예제 #10
0
def test_identificacion_consolidada_calcula_orden_de_prioridad(db):
    mc1 = MesaCategoriaFactory()
    mesa = mc1.mesa
    mc2 = MesaCategoriaFactory(mesa=mesa)
    assert mc1.coeficiente_para_orden_de_carga is None
    assert mc2.coeficiente_para_orden_de_carga is None

    # Emulo consolidación.
    i = IdentificacionFactory(status='identificada', mesa=mc1.mesa, fiscal=FiscalFactory())
    AttachmentFactory(status='identificada', mesa=mesa, identificacion_testigo=i)
    mc1.refresh_from_db()
    mc2.refresh_from_db()
    assert mc1.coeficiente_para_orden_de_carga is not None
    assert mc2.coeficiente_para_orden_de_carga is not None
예제 #11
0
def test_prioridades_mesacat_seccion_con_definicion_parcial_1(db, settings, proporcion, orden_de_llegada, prioridad):
    """
    Prioridades para una MesaCategoria de una seccion que define prioridades distintas de las standard sólo para un rango de proporciones.
    """
    definir_prioridades_seccion_categoria(settings)
    seccion_parcial = SeccionFactory(nombre="Definición parcial de prioridades no standard")
    PrioridadSchedulingFactory(seccion=seccion_parcial, desde_proporcion=2, hasta_proporcion=5, prioridad=4)

    mesa_categoria = MesaCategoriaFactory(
        categoria=categoria_standard(), mesa=crear_mesa(seccion_parcial))
    prioridades = mapa_prioridades_para_mesa_categoria(mesa_categoria)

    assert(prioridades.valor_para(proporcion, orden_de_llegada)) == prioridad
예제 #12
0
def test_prioridades_mesa_seccion_cuatro_prioridades_1000(db, settings, proporcion, orden_de_llegada, prioridad):
    """
    Prioridades para una MesaCategoria de una seccion que tiene definidas cuatro niveles de prioridad en lugar de tres, para una categoria intermedia,
    en un circuito de 1000 mesas.
    La maxima prioridad para la seccion rige hasta el 2% con un minimo de 12 mesas.
    """
    definir_prioridades_seccion_categoria(settings)

    mesa_categoria = MesaCategoriaFactory(
        categoria=categoria_gv(), mesa=mesa_en_seccion(seccion_cuatro_prioridades()))
    prioridades = mapa_prioridades_para_mesa_categoria(mesa_categoria)

    assert(prioridades.valor_para(proporcion, orden_de_llegada)) == prioridad
예제 #13
0
def test_prioridades_mesacat_standard(db, settings, proporcion, orden_de_llegada, prioridad):
    """
    Prioridades para una MesaCategoria para la cual ni la sección ni la categoría tienen
    asignadas prioridades distintas a las standard
    """

    definir_prioridades_seccion_categoria(settings)
    
    mesa_categoria = MesaCategoriaFactory(
        categoria=categoria_standard(), mesa=mesa_en_seccion(seccion_standard()))
    prioridades = mapa_prioridades_para_mesa_categoria(mesa_categoria)

    assert(prioridades.valor_para(proporcion,orden_de_llegada)) == prioridad
예제 #14
0
def test_prioridades_mesacat_categoria_y_seccion_prioritarias_1000(db, settings, proporcion, orden_de_llegada, prioridad):
    """
    Prioridades para una MesaCategoria de una seccion prioritaria, para una categoria prioritaria,
    en un circuito de 100 mesas.
    La maxima prioridad para la seccion rige hasta el 2% con un minimo de 7 mesas.
    """
    definir_prioridades_seccion_categoria(settings)

    mesa_categoria = MesaCategoriaFactory(
        categoria=categoria_pv(), mesa=mesa_en_seccion(seccion_prioritaria()))
    prioridades = mapa_prioridades_para_mesa_categoria(mesa_categoria)

    assert(prioridades.valor_para(proporcion, orden_de_llegada)) == prioridad
예제 #15
0
def test_cargar_resultados_redirige_a_parcial_si_es_necesario(
        db, fiscal_client, status, parcial):
    mesa = MesaFactory()
    a = AttachmentFactory(mesa=mesa)
    c1 = CategoriaFactory(requiere_cargas_parciales=True, sensible=True)
    m1c1 = MesaCategoriaFactory(categoria=c1,
                                coeficiente_para_orden_de_carga=0.1,
                                status=status,
                                mesa=mesa)
    response = fiscal_client.get(reverse('siguiente-accion'))
    assert response.status_code == HTTPStatus.FOUND
    assert response.url == reverse(
        'carga-parcial' if parcial else 'carga-total', args=[m1c1.id])
예제 #16
0
def test_siguiente_prioriza_seccion(db, settings):
    f = FiscalFactory()
    c = CategoriaFactory()
    # Si se pone 
    #     m1 = MesaFactory(circuito__seccion__prioridad_hasta_2=10000)
    # no funciona. 
    # Intuyo que es porque en MesaFactory, el circuito se setea mediante un LazyAttribute, 
    # y los seteos que van como argumentos de la Factory se estarían ejecutando antes de
    # que se apliquen los LazyAttribute.
    # Lo único que hice fue la prueba empírica de agregar "lugar_votacion__" antes, y ver que sí setea
    # la prioridad de la sección. No llegué a entender la documentación de factory boy en la medida necesaria.

    m1 = MesaFactory(lugar_votacion__circuito__seccion__prioridad_hasta_2=10000)
    AttachmentFactory(mesa=m1)
    mc1 = MesaCategoriaFactory(
        status=MesaCategoria.STATUS.parcial_sin_consolidar,
        categoria=c,
        mesa=m1,
    )
    mc1.actualizar_coeficiente_para_orden_de_carga()
    m2 = MesaFactory(lugar_votacion__circuito__seccion__prioridad_hasta_2=42)
    AttachmentFactory(mesa=m2)
    mc2 = MesaCategoriaFactory(
        categoria=c,
        status=MesaCategoria.STATUS.parcial_sin_consolidar,
        mesa=m2,
    )
    mc2.actualizar_coeficiente_para_orden_de_carga()
    assert mc1.percentil == 1
    assert mc1.mesa.circuito.seccion.prioridad_hasta_2 == 10000
    assert mc2.percentil == 1
    assert mc2.mesa.circuito.seccion.prioridad_hasta_2 == 42
    # Se recibe la mc de la sección más prioritaria.
    assert MesaCategoria.objects.siguiente() == mc2
    for i in range(settings.MIN_COINCIDENCIAS_CARGAS):
        mc2.asignar_a_fiscal()
    # Luego la de la sección con prioridad menos prioritaria.
    assert MesaCategoria.objects.siguiente() == mc1
예제 #17
0
def test_datos_previos_desde_metadata(db):
    o1 = OpcionFactory(tipo=Opcion.TIPOS.metadata)
    o2 = OpcionFactory()
    cat1 = CategoriaFactory(opciones=[o1, o2])
    cat1o1 = CategoriaOpcionFactory(categoria=cat1, opcion=o1, orden=1)
    cat1o2 = CategoriaOpcionFactory(categoria=cat1, opcion=o2, orden=2)

    mc = MesaCategoriaFactory(categoria=cat1,
                              status=MesaCategoria.STATUS.total_consolidada_dc)
    carga = CargaFactory(mesa_categoria=mc, tipo='total')
    VotoMesaReportadoFactory(carga=carga, opcion=o1, votos=10)
    VotoMesaReportadoFactory(carga=carga, opcion=o2, votos=12)

    # otra categoria incluye la misma metadata.
    o2 = OpcionFactory()
    cat2 = CategoriaFactory(opciones=[o1, o2])
    cat1o1 = CategoriaOpcionFactory(categoria=cat2, opcion=o1, orden=1)
    cat2o2 = CategoriaOpcionFactory(categoria=cat2, opcion=o2, orden=2)
    mc2 = MesaCategoriaFactory(categoria=cat2, mesa=mc.mesa)

    # esa mesa categoria incluye la metadata ya cargada en mc1
    assert mc2.datos_previos('parcial') == {o1.id: 10}
    assert mc2.datos_previos('total') == {o1.id: 10}
예제 #18
0
def test_cargar_resultados_redirige_a_parcial_si_es_necesario_con_scheduler(
        db, fiscal_client, status, parcial):
    mesa = MesaFactory()
    a = AttachmentFactory(mesa=mesa)
    c1 = CategoriaFactory(requiere_cargas_parciales=True, sensible=True)
    with override_config(ASIGNAR_MESA_EN_EL_MOMENTO_SI_NO_HAY_COLA=False):
        m1c1 = MesaCategoriaFactory(categoria=c1,
                                    coeficiente_para_orden_de_carga=0.1,
                                    status=status,
                                    mesa=mesa)
        scheduler()
        response = fiscal_client.get(reverse('siguiente-accion'))
        assert response.status_code == HTTPStatus.FOUND
        assert response.url == reverse(
            'carga-parcial' if parcial else 'carga-total', args=[m1c1.id])
예제 #19
0
def test_procesar_csv_categorias_faltantes_en_archivo(db, usr_unidad_basica):
    CategoriaGeneralFactory()
    d1 = DistritoFactory(numero=1)
    s1 = SeccionFactory(numero=50, distrito=d1)
    c1 = CircuitoFactory(numero='2', seccion=s1)
    m = MesaFactory(numero='4012',
                    lugar_votacion__circuito=c1,
                    electores=100,
                    circuito=c1)
    o2 = OpcionFactory(codigo='Todes')
    o3 = OpcionFactory(codigo='Juntos')
    c = CategoriaFactory(opciones=[o2, o3], nombre='Otra categoria')
    MesaCategoriaFactory(mesa=m, categoria=c)

    cant_mesas_ok, cant_mesas_parcialmente_ok, errores = CSVImporter(
        PATH_ARCHIVOS_TEST + 'info_resultados_negativos.csv',
        usr_unidad_basica).procesar()
    assert cant_mesas_ok == 0
    assert cant_mesas_parcialmente_ok == 0
    assert 'Faltan datos en el archivo de la siguiente categoría' in errores
    assert Carga.objects.count() == 0
예제 #20
0
def test_liberacion_vuelve_al_ruedo(db, settings):
    """
    Este test verifica que la acción del consolidador libera mesas que nunca recibieron resultados.
    """

    f = FiscalFactory()
    c = CategoriaFactory(prioridad=1)
    m1 = MesaFactory()
    AttachmentFactory(mesa=m1)
    mc1 = MesaCategoriaFactory(
        status=MesaCategoria.STATUS.parcial_sin_consolidar,
        categoria=c,
        coeficiente_para_orden_de_carga=1.0,
        mesa=m1
    )
    m3 = MesaFactory()
    AttachmentFactory(mesa=m3)
    mc3 = MesaCategoriaFactory(
        categoria=c,
        status=MesaCategoria.STATUS.total_en_conflicto,
        coeficiente_para_orden_de_carga=2.0,
        mesa=m3
    )
    assert MesaCategoria.objects.siguiente() == mc1

    for i in range(settings.MIN_COINCIDENCIAS_CARGAS):
        mc1.asignar_a_fiscal()
    cant_asignaciones = mc1.cant_fiscales_asignados

    # Es como si de las varias asignaciones de la mc la última sea para el fiscal f
    f.asignar_mesa_categoria(mc1)

    # Como mc1 está muy asignada, ahora me propone mc3.
    assert MesaCategoria.objects.siguiente() == mc3
    settings.TIMEOUT_TAREAS = 0
    liberar_mesacategorias_y_attachments()

    # mc1 volvió al ruedo.
    assert MesaCategoria.objects.siguiente() == mc1
    mc1.refresh_from_db()
    assert mc1.cant_fiscales_asignados == cant_asignaciones - 1
예제 #21
0
def test_datos_previos_parcial(db):
    o1 = OpcionFactory(tipo=Opcion.TIPOS.metadata)
    o2 = OpcionFactory()
    cat1 = CategoriaFactory(opciones=[o1, o2])
    cat1o1 = CategoriaOpcionFactory(categoria=cat1, opcion=o1, orden=1)
    cat1o2 = CategoriaOpcionFactory(categoria=cat1, opcion=o2, orden=2)

    # tengo una consolidación parcial
    mc = MesaCategoriaFactory(
        categoria=cat1, status=MesaCategoria.STATUS.parcial_consolidada_dc)
    carga = CargaFactory(mesa_categoria=mc, tipo='total')
    VotoMesaReportadoFactory(carga=carga, opcion=o1, votos=10)
    VotoMesaReportadoFactory(carga=carga, opcion=o2, votos=12)
    mc.carga_testigo = carga
    mc.save()

    # si pedimos datos previos para realizar una carga total, los de consolidados parciales vienen
    assert mc.datos_previos('total') == {o1.id: 10, o2.id: 12}