diff --git a/swh/web/common/identifiers.py b/swh/web/common/identifiers.py --- a/swh/web/common/identifiers.py +++ b/swh/web/common/identifiers.py @@ -140,9 +140,12 @@ revision = archive.lookup_revision(release["target"]) directory = revision["directory"] if object_type == ObjectType.CONTENT: - if not swhid_parsed.origin: - # when no origin context, content objects need to have their - # path prefixed by root directory id for proper breadcrumbs display + if ( + not swhid_parsed.origin + and swhid_parsed.anchor.object_type != ObjectType.REVISION + ): + # when no origin or revision context, content objects need to have + # their path prefixed by root directory id for breadcrumbs display query_dict["path"] = hash_to_hex(directory) + query_dict["path"] else: # remove leading slash from SWHID content path diff --git a/swh/web/tests/common/test_identifiers.py b/swh/web/tests/common/test_identifiers.py --- a/swh/web/tests/common/test_identifiers.py +++ b/swh/web/tests/common/test_identifiers.py @@ -34,6 +34,7 @@ from swh.web.tests.strategies import ( content, directory, + directory_with_files, directory_with_subdirs, origin, origin_with_multiple_visits, @@ -635,3 +636,91 @@ swhid = gen_swhid(DIRECTORY, directory, metadata={"origin": malformed_origin_url}) resolved_swhid = resolve_swhid(swhid) assert origin_url in resolved_swhid["browse_url"] + + +@given(revision()) +def test_resolve_dir_entry_swhid_with_anchor_revision(archive_data, revision): + revision_data = archive_data.revision_get(revision) + directory = revision_data["directory"] + dir_content = archive_data.directory_ls(directory) + dir_entry = random.choice(dir_content) + + rev_swhid = gen_swhid(REVISION, revision) + + if dir_entry["type"] == "rev": + return + + if dir_entry["type"] == "file": + swhid = gen_swhid( + CONTENT, + dir_entry["checksums"]["sha1_git"], + metadata={"anchor": rev_swhid, "path": f"/{dir_entry['name']}"}, + ) + + else: + swhid = gen_swhid( + DIRECTORY, + dir_entry["target"], + metadata={"anchor": rev_swhid, "path": f"/{dir_entry['name']}/"}, + ) + + browse_url = reverse( + "browse-revision", + url_args={"sha1_git": revision}, + query_params={"path": dir_entry["name"]}, + ) + + resolved_swhid = resolve_swhid(swhid) + + assert resolved_swhid["browse_url"] == browse_url + + +@given(directory_with_subdirs()) +def test_resolve_dir_entry_swhid_with_anchor_directory(archive_data, directory): + dir_content = archive_data.directory_ls(directory) + dir_entry = random.choice( + [entry for entry in dir_content if entry["type"] == "dir"] + ) + + dir_swhid = gen_swhid(DIRECTORY, directory) + + swhid = gen_swhid( + DIRECTORY, + dir_entry["target"], + metadata={"anchor": dir_swhid, "path": f"/{dir_entry['name']}/"}, + ) + browse_url = reverse( + "browse-directory", + url_args={"sha1_git": directory}, + query_params={"path": f"{dir_entry['name']}"}, + ) + + resolved_swhid = resolve_swhid(swhid) + + assert resolved_swhid["browse_url"] == browse_url + + +@given(directory_with_files()) +def test_resolve_file_entry_swhid_with_anchor_directory(archive_data, directory): + dir_content = archive_data.directory_ls(directory) + file_entry = random.choice( + [entry for entry in dir_content if entry["type"] == "file"] + ) + + dir_swhid = gen_swhid(DIRECTORY, directory) + + sha1_git = file_entry["checksums"]["sha1_git"] + swhid = gen_swhid( + CONTENT, + sha1_git, + metadata={"anchor": dir_swhid, "path": f"/{file_entry['name']}"}, + ) + browse_url = reverse( + "browse-content", + url_args={"query_string": f"sha1_git:{sha1_git}"}, + query_params={"path": f"{directory}/{file_entry['name']}"}, + ) + + resolved_swhid = resolve_swhid(swhid) + + assert resolved_swhid["browse_url"] == browse_url diff --git a/swh/web/tests/strategies.py b/swh/web/tests/strategies.py --- a/swh/web/tests/strategies.py +++ b/swh/web/tests/strategies.py @@ -223,15 +223,11 @@ return _known_swh_object("directories") -def directory_with_subdirs(): - """ - Hypothesis strategy returning a random directory containing - sub directories ingested into the test archive. - """ +def _directory_with_entry_type(type_): return directory().filter( lambda d: any( [ - e["type"] == "dir" + e["type"] == type_ for e in list( get_tests_data()["storage"].directory_ls(hash_to_bytes(d)) ) @@ -240,6 +236,22 @@ ) +def directory_with_subdirs(): + """ + Hypothesis strategy returning a random directory containing + sub directories ingested into the test archive. + """ + return _directory_with_entry_type("dir") + + +def directory_with_files(): + """ + Hypothesis strategy returning a random directory containing + at least one regular file + """ + return _directory_with_entry_type("file") + + def empty_directory(): """ Hypothesis strategy returning the empty directory ingested