예제 #1
0
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()
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
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
예제 #7
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
예제 #8
0
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
예제 #9
0
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])
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
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)
예제 #14
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)
예제 #15
0
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)
예제 #16
0
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)
예제 #17
0
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
예제 #18
0
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}
예제 #19
0
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
예제 #20
0
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')
예제 #21
0
def test_attachment_unico(db):
    a = AttachmentFactory()
    assert a.foto
    assert a.foto_digest
    with pytest.raises(IntegrityError):
        AttachmentFactory(foto=a.foto)
예제 #22
0
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
예제 #23
0
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
예제 #24
0
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
예제 #25
0
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)
예제 #26
0
def identificar_mesa(mesa, fiscal):
    attach = AttachmentFactory()
    identificar(attach, mesa, fiscal)
    consolidar_identificaciones(attach)