def test_swh_multi_response_mimetype(mocker, api_request_factory): mock_shorten_path = mocker.patch("swh.web.api.apiresponse.shorten_path") mock_filter = mocker.patch("swh.web.api.apiresponse.filter_by_fields") mock_json = mocker.patch("swh.web.api.apiresponse.json") data = {"data": [12, 34], "id": "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc"} mock_filter.return_value = data mock_shorten_path.return_value = "my_short_path" mock_json.dumps.return_value = json.dumps(data) accepted_response_formats = { "html": "text/html", "yaml": "application/yaml", "json": "application/json", } for resp_format in accepted_response_formats: request = api_request_factory.get("/api/test/path/") content_type = accepted_response_formats[resp_format] setattr(request, "accepted_media_type", content_type) rv = make_api_response(request, data) mock_filter.assert_called_with(request, data) if resp_format != "html": assert rv.status_code == 200, rv.data assert rv.data == data else: assert rv.status_code == 200, rv.content assert_contains(rv, json.dumps(data))
def test_revision_metadata_display(archive_data, client, directory, person, date): metadata = {"foo": "bar"} revision = Revision( directory=hash_to_bytes(directory), author=person, committer=person, message=b"commit message", date=TimestampWithTimezone.from_datetime(date), committer_date=TimestampWithTimezone.from_datetime(date), synthetic=False, type=RevisionType.GIT, metadata=metadata, ) archive_data.revision_add([revision]) url = reverse("browse-revision", url_args={"sha1_git": hash_to_hex(revision.id)}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/revision.html") assert_contains(resp, "swh-metadata-popover") assert_contains(resp, escape(json.dumps(metadata, indent=4)))
def test_content_view_text(client, archive_data, content): sha1_git = content["sha1_git"] url = reverse( "browse-content", url_args={"query_string": content["sha1"]}, query_params={"path": content["path"]}, ) url_raw = reverse("browse-content-raw", url_args={"query_string": content["sha1"]}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") content_display = _process_content_for_display(archive_data, content) mimetype = content_display["mimetype"] if mimetype.startswith("text/"): assert_contains(resp, '<code class="%s">' % content_display["language"]) assert_contains(resp, escape(content_display["content_data"])) assert_contains(resp, url_raw) swh_cnt_id = gen_swhid(CONTENT, sha1_git) swh_cnt_id_url = reverse("browse-swhid", url_args={"swhid": swh_cnt_id}) assert_contains(resp, swh_cnt_id) assert_contains(resp, swh_cnt_id_url) assert_not_contains(resp, "swh-metadata-popover")
def test_legacy_swhid_browse(archive_data, client, origin): snapshot = archive_data.snapshot_get_latest(origin["url"]) revision = archive_data.snapshot_get_head(snapshot) directory = archive_data.revision_get(revision)["directory"] directory_content = archive_data.directory_ls(directory) directory_file = random.choice( [e for e in directory_content if e["type"] == "file"]) legacy_swhid = gen_swhid( CONTENT, directory_file["checksums"]["sha1_git"], metadata={"origin": origin["url"]}, ) url = reverse("browse-swhid", url_args={"swhid": legacy_swhid}) resp = check_html_get_response(client, url, status_code=302) resp = check_html_get_response(client, resp["location"], status_code=200, template_used="browse/content.html") swhid = gen_swhid( CONTENT, directory_file["checksums"]["sha1_git"], metadata={ "origin": origin["url"], "visit": gen_swhid(SNAPSHOT, snapshot["id"]), "anchor": gen_swhid(REVISION, revision), }, ) assert_contains(resp, swhid)
def test_oidc_login_complete_wrong_code_verifier(client, keycloak_mock): keycloak_mock.set_auth_success(False) # simulate login process has been initialized session = client.session session["login_data"] = { "code_verifier": "", "state": str(uuid.uuid4()), "redirect_uri": "", "next_path": "", } session.save() # check authentication error is reported login_url = reverse( "oidc-login-complete", query_params={ "code": "some-code", "state": session["login_data"]["state"] }, ) # should render an error page response = check_html_get_response(client, login_url, status_code=500, template_used="error.html") request = response.wsgi_request assert_contains(response, "User authentication failed.", status_code=500) # no user should be logged in assert isinstance(request.user, AnonymousUser)
def test_oidc_login_complete_wrong_csrf_token(client, keycloak_mock): # simulate login process has been initialized session = client.session session["login_data"] = { "code_verifier": "", "state": str(uuid.uuid4()), "redirect_uri": "", "next_path": "", } session.save() # user initiates login process login_url = reverse("oidc-login-complete", query_params={ "code": "some-code", "state": "some-state" }) # should render an error page response = check_html_get_response(client, login_url, status_code=400, template_used="error.html") request = response.wsgi_request assert_contains(response, "Wrong CSRF token, aborting login process.", status_code=400) # no user should be logged in assert isinstance(request.user, AnonymousUser)
def test_oidc_login_complete_view_missing_parameters(client, mocker): # simulate login process has been initialized session = client.session session["login_data"] = { "code_verifier": "", "state": str(uuid.uuid4()), "redirect_uri": "", "next_path": "", } session.save() # user initiates login process login_url = reverse("oidc-login-complete") # should render an error page response = check_html_get_response(client, login_url, status_code=400, template_used="error.html") request = response.wsgi_request assert_contains(response, "Missing query parameters for authentication.", status_code=400) # no user should be logged in assert isinstance(request.user, AnonymousUser)
def test_revision_request_errors(client, revision, unknown_revision, new_origin): url = reverse("browse-revision", url_args={"sha1_git": unknown_revision}) resp = check_html_get_response(client, url, status_code=404, template_used="error.html") assert_contains(resp, "Revision with sha1_git %s not found" % unknown_revision, status_code=404) url = reverse( "browse-revision", url_args={"sha1_git": revision}, query_params={"origin_url": new_origin.url}, ) resp = check_html_get_response(client, url, status_code=404, template_used="error.html") assert_contains(resp, "the origin mentioned in your request" " appears broken", status_code=404)
def test_release_browse_not_found(client, archive_data, unknown_release): url = reverse("browse-release", url_args={"sha1_git": unknown_release}) resp = check_html_get_response( client, url, status_code=404, template_used="error.html" ) err_msg = "Release with sha1_git %s not found" % unknown_release assert_contains(resp, err_msg, status_code=404)
def test_browse_visits_origin_not_found(client, new_origin): url = reverse("browse-origin-visits", query_params={"origin_url": new_origin.url}) resp = check_html_get_response( client, url, status_code=404, template_used="error.html" ) assert_contains( resp, f"Origin with url {new_origin.url} not found", status_code=404 )
def test_layout_without_oidc_auth_enabled(client, mocker): config = deepcopy(get_config()) config["keycloak"]["server_url"] = "" mock_get_config = mocker.patch("swh.web.common.utils.get_config") mock_get_config.return_value = config url = reverse("swh-web-homepage") resp = check_http_get_response(client, url, status_code=200) assert_contains(resp, reverse("login"))
def test_origin_content_no_path(client, origin): url = reverse("browse-origin-content", query_params={"origin_url": origin["url"]}) resp = check_html_get_response( client, url, status_code=400, template_used="error.html" ) assert_contains( resp, "The path of a content must be given as query parameter.", status_code=400 )
def test_browse_directory_snapshot_not_found(client, mocker, origin): mock_get_snapshot_context = mocker.patch( "swh.web.browse.snapshot_context.get_snapshot_context" ) mock_get_snapshot_context.side_effect = NotFoundExc("Snapshot not found") url = reverse("browse-origin-directory", query_params={"origin_url": origin["url"]}) resp = check_html_get_response( client, url, status_code=404, template_used="error.html" ) assert_contains(resp, "Snapshot not found", status_code=404) assert mock_get_snapshot_context.called
def test_content_utf8_detected_as_binary_display(client, archive_data, content): url = reverse("browse-content", url_args={"query_string": content["sha1"]}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") content_display = _process_content_for_display(archive_data, content) assert_contains(resp, escape(content_display["content_data"]))
def test_oidc_login_complete_view_no_login_data(client, mocker): # user initiates login process login_url = reverse("oidc-login-complete") # should render an error page response = check_html_get_response(client, login_url, status_code=500, template_used="error.html") assert_contains(response, "Login process has not been initialized.", status_code=500)
def test_permalink_box_context(client, tests_data, directory): origin_url = random.choice(tests_data["origins"])["url"] url = reverse( "browse-directory", url_args={"sha1_git": directory}, query_params={"origin_url": origin_url}, ) resp = check_html_get_response(client, url, status_code=200, template_used="browse/directory.html") assert_contains(resp, 'id="swhid-context-option-directory"')
def test_origin_release_browse(client, archive_data, origin): snapshot = archive_data.snapshot_get_latest(origin["url"]) release = [ b for b in snapshot["branches"].values() if b["target_type"] == "release" ][-1] release_data = archive_data.release_get(release["target"]) revision_data = archive_data.revision_get(release_data["target"]) url = reverse( "browse-origin-directory", query_params={"origin_url": origin["url"], "release": release_data["name"]}, ) resp = check_html_get_response( client, url, status_code=200, template_used="browse/directory.html" ) assert_contains(resp, release_data["name"]) assert_contains(resp, release["target"]) swhid_context = { "origin": origin["url"], "visit": gen_swhid(SNAPSHOT, snapshot["id"]), "anchor": gen_swhid(RELEASE, release_data["id"]), } swh_dir_id = gen_swhid( DIRECTORY, revision_data["directory"], metadata=swhid_context ) swh_dir_id_url = reverse("browse-swhid", url_args={"swhid": swh_dir_id}) assert_contains(resp, swh_dir_id) assert_contains(resp, swh_dir_id_url)
def test_browse_origin_directory_no_visit(client, mocker, origin): mock_get_origin_visits = mocker.patch( "swh.web.common.origin_visits.get_origin_visits" ) mock_get_origin_visits.return_value = [] mock_archive = mocker.patch("swh.web.common.origin_visits.archive") mock_archive.lookup_origin_visit_latest.return_value = None url = reverse("browse-origin-directory", query_params={"origin_url": origin["url"]}) resp = check_html_get_response( client, url, status_code=404, template_used="error.html" ) assert_contains(resp, "No valid visit", status_code=404) assert not mock_get_origin_visits.called
def test_content_view_image_no_rendering(client, archive_data, content): url = reverse("browse-content", url_args={"query_string": content["sha1"]}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") mimetype = content["mimetype"] encoding = content["encoding"] assert_contains( resp, (f"Content with mime type {mimetype} and encoding {encoding} " "cannot be displayed."), )
def test_content_view_no_utf8_text(client, archive_data, content): sha1_git = content["sha1_git"] url = reverse("browse-content", url_args={"query_string": content["sha1"]}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") content_display = _process_content_for_display(archive_data, content) swh_cnt_id = gen_swhid(CONTENT, sha1_git) swh_cnt_id_url = reverse("browse-swhid", url_args={"swhid": swh_cnt_id}) assert_contains(resp, swh_cnt_id_url) assert_contains(resp, escape(content_display["content_data"]))
def test_directory_with_invalid_path(client, directory): path = "foo/bar" dir_url = reverse( "browse-directory", url_args={"sha1_git": directory}, query_params={"path": path}, ) resp = check_html_get_response(client, dir_url, status_code=404, template_used="browse/directory.html") error_message = ( f"Directory entry with path {path} from root directory {directory} not found" ) assert_contains(resp, error_message, status_code=404)
def test_content_view_image(client, archive_data, content): url = reverse("browse-content", url_args={"query_string": content["sha1"]}) url_raw = reverse("browse-content-raw", url_args={"query_string": content["sha1"]}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") content_display = _process_content_for_display(archive_data, content) mimetype = content_display["mimetype"] content_data = content_display["content_data"] assert_contains( resp, '<img src="data:%s;base64,%s"/>' % (mimetype, content_data)) assert_contains(resp, url_raw)
def test_origin_views_no_url_query_parameter(client): for browse_context in ( "content", "directory", "log", "branches", "releases", "visits", ): url = reverse(f"browse-origin-{browse_context}") resp = check_html_get_response( client, url, status_code=400, template_used="error.html" ) assert_contains( resp, "An origin URL must be provided as query parameter.", status_code=400 )
def test_revision_invalid_path(client, archive_data, revision): path = "foo/bar" url = reverse("browse-revision", url_args={"sha1_git": revision}, query_params={"path": path}) resp = check_html_get_response(client, url, status_code=404, template_used="browse/revision.html") directory = archive_data.revision_get(revision)["directory"] error_message = ( f"Directory entry with path {path} from root directory {directory} not found" ) assert_contains(resp, error_message, status_code=404) assert_not_contains(resp, "swh-metadata-popover", status_code=404)
def test_origin_visits_browse(client, archive_data, origin): url = reverse("browse-origin-visits", query_params={"origin_url": origin["url"]}) resp = check_html_get_response( client, url, status_code=200, template_used="browse/origin-visits.html" ) visits = archive_data.origin_visit_get(origin["url"]) for v in visits: vdate = format_utc_iso_date(v["date"], "%Y-%m-%dT%H:%M:%SZ") browse_dir_url = reverse( "browse-origin-directory", query_params={"origin_url": origin["url"], "timestamp": vdate}, ) assert_contains(resp, browse_dir_url) _check_origin_link(resp, origin["url"])
def test_origin_branches_pagination_with_alias( client, archive_data, mocker, new_origin, visit_dates, revisions, existing_release ): """ When a snapshot contains a branch or a release alias, pagination links in the branches / releases view should be displayed. """ mocker.patch("swh.web.browse.snapshot_context.PER_PAGE", len(revisions) / 2) snp_dict = {"branches": {}, "id": hash_to_bytes(random_sha1())} for i in range(len(revisions)): branch = "".join(random.choices(string.ascii_lowercase, k=8)) snp_dict["branches"][branch.encode()] = { "target_type": "revision", "target": hash_to_bytes(revisions[i]), } release = "".join(random.choices(string.ascii_lowercase, k=8)) snp_dict["branches"][b"RELEASE_ALIAS"] = { "target_type": "alias", "target": release.encode(), } snp_dict["branches"][release.encode()] = { "target_type": "release", "target": hash_to_bytes(existing_release), } archive_data.origin_add([new_origin]) archive_data.snapshot_add([Snapshot.from_dict(snp_dict)]) visit = archive_data.origin_visit_add( [OriginVisit(origin=new_origin.url, date=visit_dates[0], type="git",)] )[0] visit_status = OriginVisitStatus( origin=new_origin.url, visit=visit.visit, date=now(), status="full", snapshot=snp_dict["id"], ) archive_data.origin_visit_status_add([visit_status]) url = reverse("browse-origin-branches", query_params={"origin_url": new_origin.url}) resp = check_html_get_response( client, url, status_code=200, template_used="browse/branches.html" ) assert_contains(resp, '<ul class="pagination')
def test_content_too_large(client, mocker): mock_request_content = mocker.patch( "swh.web.browse.views.content.request_content") stub_content_too_large_data = { "checksums": { "sha1": "8624bcdae55baeef00cd11d5dfcfa60f68710a02", "sha1_git": "94a9ed024d3859793618152ea559a168bbcbb5e2", "sha256": ("8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b16" "5a1dcd80c7c545eb65b903"), "blake2s256": ("38702b7168c7785bfe748b51b45d9856070ba90" "f9dc6d90f2ea75d4356411ffe"), }, "length": 30000000, "raw_data": None, "mimetype": "text/plain", "encoding": "us-ascii", "language": "not detected", "licenses": "GPL", "error_code": 200, "error_message": "", "error_description": "", } content_sha1 = stub_content_too_large_data["checksums"]["sha1"] mock_request_content.return_value = stub_content_too_large_data url = reverse("browse-content", url_args={"query_string": content_sha1}) url_raw = reverse("browse-content-raw", url_args={"query_string": content_sha1}) resp = check_html_get_response(client, url, status_code=200, template_used="browse/content.html") assert_contains(resp, "Content is too large to be displayed") assert_contains(resp, url_raw)
def test_oidc_logout_view_failure(client, keycloak_mock): """ Simulate a failed logout operation with OpenID Connect. """ # login our test user client.login(code="", code_verifier="", redirect_uri="") err_msg = "Authentication server error" keycloak_mock.logout.side_effect = Exception(err_msg) # user initiates logout process logout_url = reverse("oidc-logout") # should render an error page response = check_html_get_response(client, logout_url, status_code=500, template_used="error.html") request = response.wsgi_request assert_contains(response, err_msg, status_code=500) # user should be logged out from Django anyway assert isinstance(request.user, AnonymousUser)
def test_origin_browse_directory_branch_with_non_resolvable_revision( client, archive_data, new_origin, unknown_revision ): branch_name = "master" snapshot = Snapshot( branches={ branch_name.encode(): SnapshotBranch( target=hash_to_bytes(unknown_revision), target_type=TargetType.REVISION, ) } ) archive_data.origin_add([new_origin]) archive_data.snapshot_add([snapshot]) visit = archive_data.origin_visit_add( [OriginVisit(origin=new_origin.url, date=now(), type="git",)] )[0] visit_status = OriginVisitStatus( origin=new_origin.url, visit=visit.visit, date=now(), status="partial", snapshot=snapshot.id, ) archive_data.origin_visit_status_add([visit_status]) url = reverse( "browse-origin-directory", query_params={"origin_url": new_origin.url, "branch": branch_name}, ) resp = check_html_get_response( client, url, status_code=200, template_used="browse/directory.html" ) assert_contains( resp, f"Revision {unknown_revision } could not be found in the archive." )
def _check_origin_snapshot_related_html(resp, origin, snapshot, snapshot_sizes, branches, releases): browse_origin_url = reverse("browse-origin", query_params={"origin_url": origin["url"]}) assert_contains(resp, f'href="{browse_origin_url}"') origin_branches_url = reverse( "browse-origin-branches", query_params={ "origin_url": origin["url"], "snapshot": snapshot["id"] }, ) assert_contains(resp, f'href="{escape(origin_branches_url)}"') assert_contains(resp, f"Branches ({snapshot_sizes['revision']})") origin_releases_url = reverse( "browse-origin-releases", query_params={ "origin_url": origin["url"], "snapshot": snapshot["id"] }, ) assert_contains(resp, f'href="{escape(origin_releases_url)}"') assert_contains(resp, f"Releases ({snapshot_sizes['release']})") assert_contains(resp, '<li class="swh-branch">', count=len(branches)) assert_contains(resp, '<li class="swh-release">', count=len(releases))