Пример #1
0
def test_audit_boards_already_created(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board",
        [{
            "name": "Audit Board #1"
        }],
    )
    assert_ok(rv)

    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board",
        [{
            "name": "Audit Board #2"
        }],
    )
    assert rv.status_code == 409
    assert json.loads(rv.data) == {
        "errors": [{
            "errorType": "Conflict",
            "message": "Audit boards already created for round 1",
        }]
    }
Пример #2
0
def audit_board_round_2_ids(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: str,
    round_2_id: str,
) -> List[str]:
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_2_id}/audit-board",
        [
            {
                "name": "Audit Board #1"
            },
            {
                "name": "Audit Board #2"
            },
            {
                "name": "Audit Board #3"
            },
        ],
    )
    assert_ok(rv)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_2_id}/audit-board"
    )
    audit_boards = json.loads(rv.data)["auditBoards"]
    return [ab["id"] for ab in audit_boards]
Пример #3
0
def test_audit_boards_create_round_2(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_2_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_2_id}/audit-board",
        [
            {
                "name": "Audit Board #1"
            },
            {
                "name": "Audit Board #2"
            },
            {
                "name": "Audit Board #3"
            },
        ],
    )
    assert_ok(rv)

    assert_ballots_got_assigned_correctly(
        jurisdiction_ids[0],
        round_2_id,
        expected_num_audit_boards=3,
        expected_num_samples=J1_SAMPLES_ROUND_2,
    )
Пример #4
0
def test_two_orgs_same_name(client: FlaskClient):
    org_id_1, _ = create_org_and_admin(user_email="*****@*****.**")
    org_id_2, _ = create_org_and_admin(user_email="*****@*****.**")
    set_logged_in_user(client, UserType.AUDIT_ADMIN, "*****@*****.**")

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id_1,
            "isMultiJurisdiction": True,
        },
    )
    assert rv.status_code == 200
    assert json.loads(rv.data)["electionId"]

    set_logged_in_user(client, UserType.AUDIT_ADMIN, "*****@*****.**")

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id_2,
            "isMultiJurisdiction": True,
        },
    )
    assert rv.status_code == 200
    assert json.loads(rv.data)["electionId"]
Пример #5
0
def test_ballot_manifest_upload_bad_csv(
    client: FlaskClient, election_id: str, jurisdiction_ids: List[str]
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={"manifest": (io.BytesIO(b"not a CSV file"), "random.txt")},
    )
    assert_ok(rv)

    bgcompute_update_ballot_manifest_file()

    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest"
    )
    compare_json(
        json.loads(rv.data),
        {
            "file": {"name": "random.txt", "uploadedAt": assert_is_date,},
            "processing": {
                "status": ProcessingStatus.ERRORED,
                "startedAt": assert_is_date,
                "completedAt": assert_is_date,
                "error": "Please submit a valid CSV file with columns separated by commas.",
            },
        },
    )
Пример #6
0
def test_ja_ballots_before_audit_boards_set_up(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/ballots"
    )
    ballots = json.loads(rv.data)["ballots"]
    assert len(ballots) == J1_BALLOTS_ROUND_1

    compare_json(
        ballots[0],
        {
            "id": assert_is_id,
            "auditBoard": None,
            "batch": {
                "id": assert_is_id,
                "name": "1",
                "tabulator": None
            },
            "position": 12,
            "status": "NOT_AUDITED",
            "interpretations": [],
        },
    )
Пример #7
0
def test_in_org_duplicate_audit_name(client: FlaskClient):
    org_id, _user_id = create_org_and_admin(user_email="*****@*****.**")
    set_logged_in_user(client, UserType.AUDIT_ADMIN, "*****@*****.**")

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id,
            "isMultiJurisdiction": True,
        },
    )
    assert rv.status_code == 200
    assert json.loads(rv.data)["electionId"]

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id,
            "isMultiJurisdiction": True,
        },
    )
    assert rv.status_code == 409
    assert json.loads(rv.data) == {
        "errors": [
            {
                "message": "An audit with name 'Test Audit' already exists within your organization",
                "errorType": "Conflict",
            }
        ]
    }
Пример #8
0
def test_audit_board_only_one_member_sign_off_happy_path(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    contest_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
):
    audit_board_id = audit_board_round_1_ids[0]
    member_1, _ = set_up_audit_board(
        client,
        election_id,
        jurisdiction_ids[0],
        contest_ids[0],
        audit_board_id,
        only_one_member=True,
    )
    set_logged_in_user(client, UserType.AUDIT_BOARD, audit_board_id)

    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_id}/sign-off",
        {
            "memberName1": member_1,
            "memberName2": ""
        },
    )
    assert_ok(rv)
Пример #9
0
def test_ballot_manifest_upload_invalid_num_ballots(
    client: FlaskClient, election_id: str, jurisdiction_ids: List[str]
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={
            "manifest": (
                io.BytesIO(
                    b"Batch Name,Number of Ballots,Storage Location,Tabulator\n"
                    b"1,not a number,Bin 2,Tabulator 1\n"
                ),
                "manifest.csv",
            )
        },
    )
    assert_ok(rv)

    bgcompute_update_ballot_manifest_file()

    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest"
    )
    compare_json(
        json.loads(rv.data),
        {
            "file": {"name": "manifest.csv", "uploadedAt": assert_is_date,},
            "processing": {
                "status": ProcessingStatus.ERRORED,
                "startedAt": assert_is_date,
                "completedAt": assert_is_date,
                "error": "Expected a number in column Number of Ballots, row 1. Got: not a number.",
            },
        },
    )
Пример #10
0
def manifests(client: FlaskClient, election_id: str,
              jurisdiction_ids: List[str]):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={
            "manifest": (
                io.BytesIO(b"Batch Name,Number of Ballots\n"
                           b"1,23\n"
                           b"2,101\n"
                           b"3,122\n"
                           b"4,400"),
                "manifest.csv",
            )
        },
    )
    assert_ok(rv)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[1]}/ballot-manifest",
        data={
            "manifest": (
                io.BytesIO(b"Batch Name,Number of Ballots\n"
                           b"1,20\n"
                           b"2,10\n"
                           b"3,220\n"
                           b"4,40"),
                "manifest.csv",
            )
        },
    )
    assert_ok(rv)
    bgcompute_update_ballot_manifest_file()
Пример #11
0
def test_audit_boards_sign_off_missing_name(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    contest_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
):
    audit_board_id = audit_board_round_1_ids[0]
    member_1, member_2 = set_up_audit_board(client, election_id,
                                            jurisdiction_ids[0],
                                            contest_ids[0], audit_board_id)
    set_logged_in_user(client, UserType.AUDIT_BOARD, audit_board_id)

    for missing_field in ["memberName1", "memberName2"]:
        sign_off_request_body = {
            "memberName1": member_1,
            "memberName2": member_2
        }
        del sign_off_request_body[missing_field]

        rv = post_json(
            client,
            f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_id}/sign-off",
            sign_off_request_body,
        )

        assert rv.status_code == 400
        assert json.loads(rv.data) == {
            "errors": [{
                "errorType": "Bad Request",
                "message": f"'{missing_field}' is a required property",
            }]
        }
Пример #12
0
def test_ballot_manifest_replace(
    client: FlaskClient, election_id: str, jurisdiction_ids: List[str]
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={
            "manifest": (
                io.BytesIO(
                    b"Batch Name,Number of Ballots,Storage Location,Tabulator\n"
                    b"1,23,Bin 2,Tabulator 1\n"
                    b"12,100,Bin 3,Tabulator 2\n"
                    b"6,0,,\n"
                ),
                "manifest.csv",
            )
        },
    )
    assert_ok(rv)

    num_files = File.query.count()

    bgcompute_update_ballot_manifest_file()

    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={
            "manifest": (
                io.BytesIO(
                    b"Batch Name,Number of Ballots,Storage Location,Tabulator\n"
                    b"1,23,Bin 2,Tabulator 1\n"
                    b"12,6,Bin 6,Tabulator 2\n"
                ),
                "manifest.csv",
            )
        },
    )
    assert_ok(rv)

    # The old file should have been deleted
    assert File.query.count() == num_files

    bgcompute_update_ballot_manifest_file()

    jurisdiction = Jurisdiction.query.get(jurisdiction_ids[0])
    assert jurisdiction.manifest_num_batches == 2
    assert jurisdiction.manifest_num_ballots == 29
    assert len(jurisdiction.batches) == 2
    assert jurisdiction.batches[0].name == "1"
    assert jurisdiction.batches[0].num_ballots == 23
    assert jurisdiction.batches[0].storage_location == "Bin 2"
    assert jurisdiction.batches[0].tabulator == "Tabulator 1"
    assert jurisdiction.batches[1].name == "12"
    assert jurisdiction.batches[1].num_ballots == 6
    assert jurisdiction.batches[1].storage_location == "Bin 6"
    assert jurisdiction.batches[1].tabulator == "Tabulator 2"
Пример #13
0
def test_ja_ballot_retrieval_list_bad_round_id(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/invalid-round-id/retrieval-list"
    )
    assert rv.status_code == 404
Пример #14
0
def test_audit_boards_list_empty(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board",
    )
    audit_boards = json.loads(rv.data)
    assert audit_boards == {"auditBoards": []}
Пример #15
0
 def run_audit_board_flow(jurisdiction_id: str, audit_board_id: str):
     member_1, member_2 = set_up_audit_board(client, election_id,
                                             jurisdiction_id,
                                             contest_ids[0], audit_board_id)
     set_logged_in_user(client, UserType.AUDIT_BOARD, audit_board_id)
     rv = post_json(
         client,
         f"/election/{election_id}/jurisdiction/{jurisdiction_id}/round/{round_1_id}/audit-board/{audit_board_id}/sign-off",
         {
             "memberName1": member_1,
             "memberName2": member_2
         },
     )
     assert_ok(rv)
Пример #16
0
def test_audit_boards_bad_round_id(
        client: FlaskClient,
        election_id: str,
        jurisdiction_ids: List[str],
        round_1_id: str,  # pylint: disable=unused-argument
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/not-a-valid-id/audit-board",
        [{
            "name": "Audit Board #1"
        }],
    )
    assert rv.status_code == 404
Пример #17
0
def test_ab_audit_ballot_not_found(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
):
    set_logged_in_user(client, UserType.AUDIT_BOARD,
                       audit_board_round_1_ids[0])
    rv = put_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_round_1_ids[0]}/ballots/not-a-real-ballot-id",
        {},
    )
    assert rv.status_code == 404
Пример #18
0
def test_ballot_manifest_upload_missing_file(
    client: FlaskClient, election_id: str, jurisdiction_ids: List[str]
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.put(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/ballot-manifest",
        data={},
    )
    assert rv.status_code == 400
    assert json.loads(rv.data) == {
        "errors": [
            {
                "errorType": "Bad Request",
                "message": "Missing required file parameter 'manifest'",
            }
        ]
    }
Пример #19
0
def test_ja_ballot_retrieval_list_round_2(
        client: FlaskClient,
        election_id: str,
        jurisdiction_ids: List[str],
        round_2_id: str,
        audit_board_round_2_ids: str,  # pylint: disable=unused-argument
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_2_id}/retrieval-list"
    )
    assert rv.status_code == 200
    assert "attachment; filename=" in rv.headers["Content-Disposition"]

    retrieval_list = rv.data.decode("utf-8").replace("\r\n", "\n")
    assert len(retrieval_list.splitlines()) == J1_BALLOTS_ROUND_2 + 1
    assert retrieval_list == EXPECTED_RETRIEVAL_LIST_ROUND_2
Пример #20
0
def test_audit_board_contests_list_empty(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
    json_contests: List[JSONDict],
):
    rv = put_json(client, f"/election/{election_id}/contest",
                  [json_contests[1]])
    assert_ok(rv)
    set_logged_in_user(client,
                       UserType.AUDIT_BOARD,
                       user_key=audit_board_round_1_ids[0])
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_round_1_ids[0]}/contest"
    )
    assert json.loads(rv.data) == {"contests": []}
Пример #21
0
def test_ja_ballot_retrieval_list_before_audit_boards_set_up(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/retrieval-list"
    )
    assert rv.status_code == 200
    assert "attachment; filename=" in rv.headers["Content-Disposition"]

    retrieval_list = rv.data.decode("utf-8").replace("\r\n", "\n")
    assert (
        retrieval_list ==
        "Batch Name,Ballot Number,Storage Location,Tabulator,Ticket Numbers,Already Audited,Audit Board\n"
    )
Пример #22
0
def round_2_id(
        client: FlaskClient,
        election_id: str,
        contest_ids: str,
        round_1_id: str,
        audit_board_round_1_ids: List[str],  # pylint: disable=unused-argument
) -> str:
    run_audit_round(round_1_id, contest_ids[0], 0.5)

    set_logged_in_user(client, UserType.AUDIT_ADMIN, DEFAULT_AA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/round",
        {"roundNum": 2},
    )
    assert_ok(rv)

    rv = client.get(f"/election/{election_id}/round", )
    rounds = json.loads(rv.data)["rounds"]
    return str(rounds[1]["id"])
Пример #23
0
def test_in_org_with_logged_in_admin(client: FlaskClient):
    org_id, _user_id = create_org_and_admin(user_email="*****@*****.**")
    set_logged_in_user(client, UserType.AUDIT_ADMIN, "*****@*****.**")

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id,
            "isMultiJurisdiction": True,
        },
    )
    response = json.loads(rv.data)
    election_id = response.get("electionId", None)
    assert election_id, response

    rv = client.get(f"/election/{election_id}/audit/status")

    assert json.loads(rv.data)["organizationId"] == org_id
Пример #24
0
def round_1_id(
        client: FlaskClient,
        election_id: str,
        jurisdiction_ids: List[str],  # pylint: disable=unused-argument
        contest_ids: str,  # pylint: disable=unused-argument
        election_settings,  # pylint: disable=unused-argument
        manifests,  # pylint: disable=unused-argument
) -> str:
    set_logged_in_user(client, UserType.AUDIT_ADMIN, DEFAULT_AA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/round",
        {
            "roundNum": 1,
            "sampleSize": SAMPLE_SIZE_ROUND_1
        },
    )
    assert_ok(rv)
    rv = client.get(f"/election/{election_id}/round", )
    rounds = json.loads(rv.data)["rounds"]
    return str(rounds[0]["id"])
Пример #25
0
def test_audit_boards_missing_field(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board",
        [{}, {
            "name": "Audit Board #2"
        }],
    )
    assert rv.status_code == 400
    assert json.loads(rv.data) == {
        "errors": [{
            "errorType": "Bad Request",
            "message": "'name' is a required property",
        }]
    }
Пример #26
0
def test_audit_boards_wrong_round(
        client: FlaskClient,
        election_id: str,
        jurisdiction_ids: List[str],
        round_1_id: str,
        round_2_id: str,  # pylint: disable=unused-argument
):
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, DEFAULT_JA_EMAIL)
    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board",
        [{
            "name": "Audit Board #1"
        }],
    )
    assert rv.status_code == 409
    assert json.loads(rv.data) == {
        "errors": [{
            "errorType": "Conflict",
            "message": "Round 1 is not the current round",
        }]
    }
Пример #27
0
def test_in_org_with_logged_in_jurisdiction_admin(client: FlaskClient):
    org_id, _user_id = create_org_and_admin(user_email="*****@*****.**")
    set_logged_in_user(client, UserType.JURISDICTION_ADMIN, "*****@*****.**")

    rv = post_json(
        client,
        "/election/new",
        {
            "auditName": "Test Audit",
            "organizationId": org_id,
            "isMultiJurisdiction": True,
        },
    )
    assert json.loads(rv.data) == {
        "errors": [
            {
                "message": f"User is not logged in as an audit admin and so does not have access to organization {org_id}",
                "errorType": "Forbidden",
            }
        ]
    }
    assert rv.status_code == 403
Пример #28
0
def test_audit_board_contests_list(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
    json_contests: List[JSONDict],
):
    rv = put_json(client, f"/election/{election_id}/contest", json_contests)
    assert_ok(rv)

    set_logged_in_user(client,
                       UserType.AUDIT_BOARD,
                       user_key=audit_board_round_1_ids[0])
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_round_1_ids[0]}/contest"
    )
    contests = json.loads(rv.data)
    expected_contests = [{
        **contest, "currentRoundStatus": None
    } for contest in [json_contests[0], json_contests[2]]]
    assert contests == {"contests": expected_contests}
Пример #29
0
def test_audit_boards_sign_off_before_finished(
    client: FlaskClient,
    election_id: str,
    jurisdiction_ids: List[str],
    contest_ids: List[str],
    round_1_id: str,
    audit_board_round_1_ids: List[str],
):
    audit_board_id = audit_board_round_1_ids[0]
    member_1, member_2 = set_up_audit_board(client, election_id,
                                            jurisdiction_ids[0],
                                            contest_ids[0], audit_board_id)
    set_logged_in_user(client, UserType.AUDIT_BOARD, audit_board_id)

    # Undo some of the ballot auditing done by set_up_audit_board
    ballots = SampledBallot.query.filter_by(
        audit_board_id=audit_board_id).all()
    for ballot in ballots[:10]:
        ballot.status = BallotStatus.NOT_AUDITED
    db.session.commit()

    rv = post_json(
        client,
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_1_id}/audit-board/{audit_board_id}/sign-off",
        {
            "memberName1": member_1,
            "memberName2": member_2
        },
    )
    assert rv.status_code == 409
    assert json.loads(rv.data) == {
        "errors": [{
            "errorType":
            "Conflict",
            "message":
            "Audit board is not finished auditing all assigned ballots",
        }]
    }
Пример #30
0
def test_ab_list_ballots_round_2(
        client: FlaskClient,
        election_id: str,
        jurisdiction_ids: List[str],
        round_2_id: str,
        audit_board_round_2_ids: List[str],  # pylint: disable=unused-argument
):
    set_logged_in_user(client, UserType.AUDIT_BOARD,
                       audit_board_round_2_ids[0])
    rv = client.get(
        f"/election/{election_id}/jurisdiction/{jurisdiction_ids[0]}/round/{round_2_id}/audit-board/{audit_board_round_2_ids[0]}/ballots"
    )
    ballots = json.loads(rv.data)["ballots"]
    assert len(ballots) == AB1_BALLOTS_ROUND_2

    compare_json(
        ballots[0],
        {
            "id": assert_is_id,
            "batch": {
                "id": assert_is_id,
                "name": "4",
                "tabulator": None
            },
            "position": 3,
            "status": "NOT_AUDITED",
            "interpretations": [],
            "auditBoard": {
                "id": assert_is_id,
                "name": "Audit Board #1"
            },
        },
    )

    previously_audited_ballots = [
        b for b in ballots if b["status"] == "AUDITED"
    ]
    assert len(previously_audited_ballots) == 22