def test_homepage_dashboard_flagged(user: User, user2: User, package: Package): pkgbase = package.PackageBase now = time.utcnow() with db.begin(): db.create(PackageComaintainer, User=user2, PackageBase=pkgbase, Priority=1) pkgbase.OutOfDateTS = now - 5 pkgbase.Flagger = user # Test that a comaintainer viewing the dashboard shows them their # flagged co-maintained packages. comaint_cookies = {"AURSID": user2.login(Request(), "testPassword")} with client as request: resp = request.get("/", cookies=comaint_cookies) assert resp.status_code == int(HTTPStatus.OK) root = parse_root(resp.text) flagged = root.xpath('//table[@id="flagged-packages"]//tr/td/a')[0] assert flagged.text.strip() == package.Name # Test that a maintainer viewing the dashboard shows them their # flagged maintained packages. cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: resp = request.get("/", cookies=cookies) assert resp.status_code == int(HTTPStatus.OK) root = parse_root(resp.text) flagged = root.xpath('//table[@id="flagged-packages"]//tr/td/a')[0] assert flagged.text.strip() == package.Name
def test_get_request_language(): """ First, tests default_lang, then tests a modified AURLANG cookie. """ request = Request() assert l10n.get_request_language(request) == "en" request.cookies["AURLANG"] = "de" assert l10n.get_request_language(request) == "de"
async def test_auth_backend_invalid_sid(backend: BasicAuthBackend): # Provide a fake AURSID that won't be found in the database. # This results in our path going down the invalid sid route, # which gives us an AnonymousUser. request = Request() request.cookies["AURSID"] = "fake" _, result = await backend.authenticate(request) assert not result.is_authenticated()
def test_get_translator_for_request(): """ Make sure that get_translator_for_request is giving us back our expected translation function. """ request = Request() request.cookies["AURLANG"] = "de" translate = l10n.get_translator_for_request(request) assert translate("Home") == "Startseite"
def test_get_raw_translator_for_request(): """ Make sure that get_raw_translator_for_request is giving us the translator we expect. """ request = Request() request.cookies["AURLANG"] = "de" translator = l10n.get_raw_translator_for_request(request) assert translator.gettext("Home") == \ l10n.translator.translate("Home", "de")
def test_tn_filter(): request = Request() request.cookies["AURLANG"] = "en" context = {"language": "en", "request": request} translated = filters.tn(context, 1, "%d package found.", "%d packages found.") assert translated == "%d package found." translated = filters.tn(context, 2, "%d package found.", "%d packages found.") assert translated == "%d packages found."
async def test_basic_auth_backend(user: User, backend: BasicAuthBackend): # This time, everything matches up. We expect the user to # equal the real_user. now_ts = time.utcnow() with db.begin(): db.create(Session, UsersID=user.ID, SessionID="realSession", LastUpdateTS=now_ts + 5) request = Request() request.cookies["AURSID"] = "realSession" _, result = await backend.authenticate(request) assert result == user
async def test_error_or_result(): async def route(request: fastapi.Request): raise RuntimeError("No response returned.") response = await util.error_or_result(route, Request()) assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR data = json.loads(response.body) assert data.get("error") == "No response returned." async def good_route(request: fastapi.Request): return JSONResponse() response = await util.error_or_result(good_route, Request()) assert response.status_code == HTTPStatus.OK
def test_tu_proposal_vote_cant_self_vote(client, proposal): tu_user, user, voteinfo = proposal # Update voteinfo.User. with db.begin(): voteinfo.User = tu_user.Username cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: data = {"decision": "Yes"} response = request.post(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.BAD_REQUEST) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "You cannot vote in an proposal about you." with client as request: data = {"decision": "Yes"} response = request.get(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.OK) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "You cannot vote in an proposal about you."
def test_tu_proposal_vote_unauthorized(client: TestClient, proposal: Tuple[User, User, TUVoteInfo]): tu_user, user, voteinfo = proposal with db.begin(): tu_user.AccountTypeID = DEVELOPER_ID cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: data = {"decision": "Yes"} response = request.post(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.UNAUTHORIZED) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "Only Trusted Users are allowed to vote." with client as request: data = {"decision": "Yes"} response = request.get(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.OK) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "Only Trusted Users are allowed to vote."
def test_tu_proposal_vote(client, proposal): tu_user, user, voteinfo = proposal # Store the current related values. yes = voteinfo.Yes cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: data = {"decision": "Yes"} response = request.post(f"/tu/{voteinfo.ID}", cookies=cookies, data=data) assert response.status_code == int(HTTPStatus.OK) # Check that the proposal record got updated. assert voteinfo.Yes == yes + 1 # Check that the new TUVote exists. vote = db.query(TUVote, TUVote.VoteInfo == voteinfo, TUVote.User == tu_user).first() assert vote is not None root = parse_root(response.text) # Check that we're told we've voted. status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "You've already voted for this proposal."
def test_ratelimit_redis(get: mock.MagicMock, getboolean: mock.MagicMock, getint: mock.MagicMock, pipeline: Pipeline): """ This test will only cover aurweb.ratelimit's Redis path if a real Redis server is configured. Otherwise, it'll use the database. """ # We'll need a Request for everything here. request = Request() # Run check_ratelimit for our request_limit. These should succeed. for i in range(4): assert not check_ratelimit(request) # This check_ratelimit should fail, being the 4001th request. assert check_ratelimit(request) # Delete the Redis keys. host = request.client.host pipeline.delete(f"ratelimit-ws:{host}") pipeline.delete(f"ratelimit:{host}") one, two = pipeline.execute() assert one and two # Should be good to go again! assert not check_ratelimit(request)
def test_homepage_dashboard(redis, packages, user): # Create Comaintainer records for all of the packages. with db.begin(): for pkg in packages: db.create(PackageComaintainer, PackageBase=pkg.PackageBase, User=user, Priority=1) cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: response = request.get("/", cookies=cookies) assert response.status_code == int(HTTPStatus.OK) root = parse_root(response.text) # Assert some expectations that we end up getting all fifty # packages in the "My Packages" table. expectations = [f"pkg_{i}" for i in range(50 - 1, 0, -1)] my_packages = root.xpath('//table[@id="my-packages"]/tbody/tr') for i, expected in enumerate(expectations): name, version, votes, pop, voted, notify, desc, maint \ = my_packages[i].xpath('./td') assert name.xpath('./a').pop(0).text.strip() == expected # Do the same for the Comaintained Packages table. my_packages = root.xpath('//table[@id="comaintained-packages"]/tbody/tr') for i, expected in enumerate(expectations): name, version, votes, pop, voted, notify, desc, maint \ = my_packages[i].xpath('./td') assert name.xpath('./a').pop(0).text.strip() == expected
def test_tu_proposal_vote_already_voted(client, proposal): tu_user, user, voteinfo = proposal with db.begin(): db.create(TUVote, VoteInfo=voteinfo, User=tu_user) voteinfo.Yes += 1 voteinfo.ActiveTUs += 1 cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: data = {"decision": "Yes"} response = request.post(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.BAD_REQUEST) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "You've already voted for this proposal." with client as request: data = {"decision": "Yes"} response = request.get(f"/tu/{voteinfo.ID}", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.OK) root = parse_root(response.text) status = root.xpath('//span[contains(@class, "status")]/text()')[0] assert status == "You've already voted for this proposal."
def test_tu_addvote_post_bylaws(client: TestClient, tu_user: User): # Bylaws votes do not need a user specified. cookies = {"AURSID": tu_user.login(Request(), "testPassword")} data = {"type": "bylaws", "agenda": "Blah blah!"} with client as request: response = request.post("/addvote", cookies=cookies, data=data) assert response.status_code == int(HTTPStatus.SEE_OTHER)
def test_tu_index_unauthorized(client: TestClient, user: User): cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: # Login as a normal user, not a TU. response = request.get("/tu", cookies=cookies, allow_redirects=False) assert response.status_code == int(HTTPStatus.SEE_OTHER) assert response.headers.get("location") == "/"
def test_tu_addvote_post_invalid_agenda(client: TestClient, tu_user: User, user: User): cookies = {"AURSID": tu_user.login(Request(), "testPassword")} data = {"user": user.Username, "type": "add_tu"} with client as request: response = request.post("/addvote", cookies=cookies, data=data) assert response.status_code == int(HTTPStatus.BAD_REQUEST)
def tu_user() -> User: """ Yield an authenticated Trusted User instance. """ user = create_user("test_tu", "*****@*****.**") with db.begin(): user.AccountTypeID = TRUSTED_USER_ID cookies = {"AURSID": user.login(Request(), "testPassword")} user.cookies = cookies yield user
def test_requests_close(client: TestClient, user: User, pkgreq: PackageRequest): cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: resp = request.get(f"/requests/{pkgreq.ID}/close", cookies=cookies, allow_redirects=False) assert resp.status_code == int(HTTPStatus.OK)
async def test_asgi_http_exception_handler(): exc = HTTPException(status_code=422, detail="EXCEPTION!") phrase = http.HTTPStatus(exc.status_code).phrase response = await aurweb.asgi.http_exception_handler(Request(), exc) assert response.status_code == 422 content = response.body.decode() assert f"{exc.status_code} - {phrase}" in content assert "EXCEPTION!" in content
def test_requests_close_unauthorized(client: TestClient, maintainer: User, pkgreq: PackageRequest): cookies = {"AURSID": maintainer.login(Request(), "testPassword")} with client as request: resp = request.get(f"/requests/{pkgreq.ID}/close", cookies=cookies, allow_redirects=False) assert resp.status_code == int(HTTPStatus.SEE_OTHER) assert resp.headers.get("location") == "/"
def test_user_login_banned(user: User): # Add ban for the next 30 seconds. banned_timestamp = datetime.utcnow() + timedelta(seconds=30) with db.begin(): db.create(Ban, IPAddress="127.0.0.1", BanTS=banned_timestamp) request = Request() request.client.host = "127.0.0.1" assert not user.login(request, "testPassword")
async def test_expired_session(backend: BasicAuthBackend, user: User): """ Login, expire the session manually, then authenticate. """ # First, build a Request with a logged in user. request = Request() request.user = user sid = request.user.login(Request(), "testPassword") request.cookies["AURSID"] = sid # Set Session.LastUpdateTS to 20 seconds expired. timeout = config.getint("options", "login_timeout") now_ts = time.utcnow() with db.begin(): request.user.session.LastUpdateTS = now_ts - timeout - 20 # Run through authentication backend and get the session # deleted due to its expiration. await backend.authenticate(request) session = db.query(Session).filter(Session.SessionID == sid).first() assert session is None
def pager_context(num_packages: int) -> Dict[str, Any]: return { "request": Request(), "singular": "%d package found.", "plural": "%d packages found.", "prefix": "/packages", "total": num_packages, "O": 0, "PP": 50 }
def test_tu_proposal_vote_not_found(client, tu_user): """ Test POST request to a missing vote. """ cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: data = {"decision": "Yes"} response = request.post("/tu/1", cookies=cookies, data=data, allow_redirects=False) assert response.status_code == int(HTTPStatus.NOT_FOUND)
def test_tu_addvote_invalid_type(client: TestClient, tu_user: User): cookies = {"AURSID": tu_user.login(Request(), "testPassword")} with client as request: response = request.get("/addvote", params={"type": "faketype"}, cookies=cookies) assert response.status_code == int(HTTPStatus.OK) root = parse_root(response.text) error = root.xpath('//*[contains(@class, "error")]/text()')[0] assert error.strip() == "Invalid type."
def test_user_login_with_outdated_sid(user: User): # Make a session with a LastUpdateTS 5 seconds ago, causing # user.login to update it with a new sid. with db.begin(): db.create(Session, UsersID=user.ID, SessionID="stub", LastUpdateTS=datetime.utcnow().timestamp() - 5) sid = user.login(Request(), "testPassword") assert sid and user.is_authenticated() assert sid != "stub"
def test_archdev_navbar_authenticated(client: TestClient, user: User): expected = ["Dashboard", "Packages", "Requests", "My Account", "Logout"] cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: resp = request.get("/", cookies=cookies) assert resp.status_code == int(HTTPStatus.OK) root = parse_root(resp.text) items = root.xpath('//div[@id="archdev-navbar"]/ul/li/a') for i, item in enumerate(items): assert item.text.strip() == expected[i]
def test_authenticated_request_timezone(): # Modify a fake request to be authenticated with the # America/Los_Angeles timezone. request = Request() request.user.authenticated = True request.user.Timezone = "America/Los_Angeles" # Get the request's timezone, it should be America/Los_Angeles. tz = get_request_timezone(request) assert tz == request.user.Timezone assert tz == "America/Los_Angeles"
def test_tu_addvote_post(client: TestClient, tu_user: User, user: User): cookies = {"AURSID": tu_user.login(Request(), "testPassword")} data = {"user": user.Username, "type": "add_tu", "agenda": "Blah"} with client as request: response = request.post("/addvote", cookies=cookies, data=data) assert response.status_code == int(HTTPStatus.SEE_OTHER) voteinfo = db.query(TUVoteInfo, TUVoteInfo.Agenda == "Blah").first() assert voteinfo is not None