示例#1
0
def test_detalle_mesa_categoria(db, fiscal_client):
    opcs = OpcionFactory.create_batch(3)
    e1 = CategoriaFactory(opciones=opcs)
    e2 = CategoriaFactory(opciones=opcs)
    mesa = MesaFactory(categorias=[e1, e2])
    c1 = CargaFactory(mesa_categoria__mesa=mesa,
                      mesa_categoria__categoria=e1,
                      tipo=Carga.TIPOS.parcial,
                      origen=Carga.SOURCES.csv)
    mc = c1.mesa_categoria
    votos1 = VotoMesaReportadoFactory(
        opcion=opcs[0],
        votos=1,
        carga=c1,
    )
    votos2 = VotoMesaReportadoFactory(
        opcion=opcs[1],
        votos=2,
        carga=c1,
    )
    votos3 = VotoMesaReportadoFactory(
        opcion=opcs[2],
        votos=1,
        carga=c1,
    )

    # a otra carga
    VotoMesaReportadoFactory(opcion=opcs[2], votos=1)
    c1.actualizar_firma()
    consumir_novedades_y_actualizar_objetos([mc])
    assert mc.carga_testigo == c1
    url = reverse('detalle-mesa-categoria', args=[e1.id, mesa.numero])
    response = fiscal_client.get(url)

    assert list(response.context['reportados']) == [votos1, votos2, votos3]
示例#2
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)
示例#3
0
def test_mesa_de_circuito__url_mesa_con_resultados(carta_marina, fiscal_client):
    # resultados para mesa 1
    mesa1, *otras_mesas = carta_marina
    categoria = mesa1.categorias.get()  # sólo default
  
    # Esto no debería ser necesario si configuramos correctamente las opciones prioritarias en carta_marina
    CategoriaOpcion.objects.filter(categoria=categoria).update(prioritaria=True)

    # opciones a partido
    o1, o2, o3, o4 = categoria.opciones.filter(partido__isnull=False)
    # la opción 4 pasa a ser del mismo partido que la 1
    o4.partido = o1.partido
    o4.save()

    blanco = Opcion.blancos()
    total = Opcion.total_votos()

    mc1 = MesaCategoria.objects.get(mesa=mesa1, categoria=categoria)
    carga = CargaFactory(mesa_categoria=mc1, tipo=Carga.TIPOS.parcial)

    consumir_novedades_y_actualizar_objetos([mesa1])

    VotoMesaReportadoFactory(carga=carga, opcion=o1, votos=20)
    VotoMesaReportadoFactory(carga=carga, opcion=o2, votos=30)
    VotoMesaReportadoFactory(carga=carga, opcion=o3, votos=40)
    VotoMesaReportadoFactory(carga=carga, opcion=o4, votos=5)

    # votaron 95/100 personas
    VotoMesaReportadoFactory(carga=carga, opcion=blanco, votos=5)
    VotoMesaReportadoFactory(carga=carga, opcion=total, votos=100)

    carga.actualizar_firma()

    assert carga.es_testigo.exists()

    query_string_mesa_1 = (
        f'?mesa={mesa1.id}&circuito={mesa1.circuito.id}'
        '&tipoDeAgregacion=todas_las_cargas'
        f'&opcionaConsiderar={OPCIONES_A_CONSIDERAR.prioritarias}'
        )
    url_mesa_1 = reverse('mesas-circuito', args=[categoria.id]) + query_string_mesa_1
    response = fiscal_client.get(url_mesa_1)

    assert response.status_code == 200

    content = response.content.decode('utf8')
    assert response.context['mensaje_no_hay_info'] not in content

    resultados = response.context['resultados']
    assert len(resultados) == 6  # 4 opciones + blanco + total

    for voto_mesa_reportado in resultados:
        assert f'<th>{voto_mesa_reportado.opcion}</th>' in content
        assert f'<td>{voto_mesa_reportado.votos}</td>' in content
示例#4
0
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
示例#5
0
def test_excluir_fiscal_que_ya_cargo(db, settings):
    """
    Se verifica que no se propone una MesaCategoria para cargar, a un fiscal que ya hizo una carga
    sobre esa MesaCategoria.
    """
    settings.MIN_COINCIDENCIAS_IDENTIFICACION = 1
    settings.MIN_COINCIDENCIAS_CARGAS = 2
    fiscal_1 = nuevo_fiscal()
    fiscal_2 = nuevo_fiscal()
    fiscal_3 = nuevo_fiscal()
    pv = CategoriaFactory(nombre="PV")
    gv = CategoriaFactory(nombre="GV")
    # hago que la categoria pv sea prioritaria
    PrioridadSchedulingFactory(categoria=pv, desde_proporcion=0, hasta_proporcion=100, prioridad=30)

    mesa = MesaFactory(numero="51", categorias=[gv, pv])
    identificar_mesa(mesa, fiscal_3)
    mesacat_pv = MesaCategoria.objects.filter(mesa=mesa, categoria=pv).first()
    mesacat_gv = MesaCategoria.objects.filter(mesa=mesa, categoria=gv).first()

    # antes de cargar, la siguiente mesacat para ambos fiscales es pv, que es más prioritaria
    mesacat_fiscal_2 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_2).mas_prioritaria()
    mesacat_fiscal_3 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_3).mas_prioritaria()
    assert mesacat_fiscal_2 == mesacat_pv
    assert mesacat_fiscal_3 == mesacat_pv

    # agrego una carga 
    carga = CargaFactory(mesa_categoria=mesacat_pv, fiscal=fiscal_2, tipo=Carga.TIPOS.parcial)

    # la siguiente mesacat para el fiscal_2 es gv, porque de pv ya hizo una carga
    # la del fiscal 3 es pv, que es más prioritaria
    mesacat_fiscal_2 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_2).mas_prioritaria()
    mesacat_fiscal_3 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_3).mas_prioritaria()
    assert mesacat_fiscal_2 == mesacat_gv
    assert mesacat_fiscal_3 == mesacat_pv

    # el fiscal 2 carga la mesacat que le queda
    carga = CargaFactory(mesa_categoria=mesacat_gv, fiscal=fiscal_2, tipo=Carga.TIPOS.parcial)

    # ahora el fiscal 2 no tiene mesacat para cargar, el fiscal 3 sigue con pv como prioritaria
    mesacat_fiscal_2 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_2).mas_prioritaria()
    mesacat_fiscal_3 = MesaCategoria.objects.con_carga_pendiente().sin_cargas_del_fiscal(fiscal_3).mas_prioritaria()
    assert mesacat_fiscal_2 == None
    assert mesacat_fiscal_3 == mesacat_pv
def test_chequear_resultado_categoria_desactivada(db, fiscal_client):
    opcs = OpcionFactory.create_batch(3, es_contable=True)
    e1 = CategoriaFactory(opciones=opcs)
    assert e1.activa is True
    mesa = MesaFactory(categoria=[e1])
    # existe una carga para esa categoria / mesa
    CargaFactory(mesa=mesa, categoria=e1)
    url = reverse('chequear-resultado-mesa', args=[e1.id, mesa.numero])
    response = fiscal_client.get(url)
    assert response.status_code == 200
    e1.activa = False
    e1.save()
    response = fiscal_client.get(url)
    assert response.status_code == 404
示例#7
0
def nueva_carga(mesa_categoria,
                fiscal,
                votos_opciones,
                tipo_carga=Carga.TIPOS.total):
    carga = CargaFactory(mesa_categoria=mesa_categoria,
                         fiscal=fiscal,
                         tipo=tipo_carga)
    for opcionVoto, cantidadVotos in zip(
            mesa_categoria.categoria.opciones.order_by('nombre'),
            votos_opciones):
        VotoMesaReportadoFactory(carga=carga,
                                 opcion=opcionVoto,
                                 votos=cantidadVotos)
    return carga
示例#8
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}
示例#9
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)
示例#10
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}
示例#11
0
def test_formset_reusa_metadata(db, fiscal_client, admin_user):
    # Hay una categoria con una opcion metadata ya consolidada.
    o1 = OpcionFactory(tipo=Opcion.TIPOS.metadata)
    cat1 = CategoriaFactory(opciones=[o1])
    from elecciones.models import CategoriaOpcion
    # Me aseguro de que no estuviese asociada con otro orden.
    CategoriaOpcion.objects.filter(categoria=cat1, opcion=o1).delete()
    cat1op1 = CategoriaOpcionFactory(categoria=cat1, opcion=o1, orden=1)
    mc = MesaCategoriaFactory(categoria=cat1,
                              status=MesaCategoria.STATUS.total_consolidada_dc)
    carga = CargaFactory(mesa_categoria=mc, tipo='total')
    VotoMesaReportadoFactory(carga=carga, opcion=o1, votos=10)

    # Otra categoría incluye la misma metadata.
    o2 = OpcionFactory()
    cat2 = CategoriaFactory(opciones=[o1, o2])
    # Me aseguro de que no estuviesen asociadas con otro orden.
    CategoriaOpcion.objects.filter(categoria=cat2, opcion=o1).delete()
    CategoriaOpcion.objects.filter(categoria=cat2, opcion=o2).delete()
    cat2op1 = CategoriaOpcionFactory(categoria=cat2, opcion=o1, orden=1)
    cat2op1 = CategoriaOpcionFactory(categoria=cat2, opcion=o2, orden=2)
    mc2 = MesaCategoriaFactory(categoria=cat2, mesa=mc.mesa)

    mc2.asignar_a_fiscal()
    admin_user.fiscal.asignar_mesa_categoria(mc2)
    response = fiscal_client.get(reverse('carga-total', args=[mc2.id]))
    assert len(response.context['formset']) == 2 + len(
        Opcion.opciones_no_partidarias_obligatorias())
    assert response.context['formset'][0].initial['opcion'] == o1
    assert response.context['formset'][1].initial['opcion'] == o2

    # y los valores de los votos
    assert response.context['formset'][0].initial['votos'] == 10
    assert response.context['formset'][0].fields['votos'].widget.attrs[
        'readonly'] is True

    assert response.context['formset'][1].initial['votos'] is None
示例#12
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)
示例#13
0
def reportar_problema_mesa_categoria(mesa_categoria, fiscal):
    return CargaFactory(mesa_categoria=mesa_categoria,
                        fiscal=fiscal,
                        tipo=Carga.TIPOS.problema)