Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/web/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ inline auto make_file_manager_table_header(sourcemeta::core::HTMLWriter &writer)
}

inline auto make_file_manager(sourcemeta::core::HTMLWriter &writer,
const sourcemeta::core::JSON &directory) -> void {
const sourcemeta::core::JSON &directory,
const std::string &base_path) -> void {
if (directory.at("entries").empty()) {
writer.div().attribute("class", "container-fluid p-4 flex-grow-1");
writer.p(
Expand All @@ -318,12 +319,15 @@ inline auto make_file_manager(sourcemeta::core::HTMLWriter &writer,
return;
}

const auto self_path{base_path + "/self"};
const auto self_path_slash{base_path + "/self/"};

// First pass: check what we have
bool has_regular_entries = false;
bool has_special_entries = false;
for (const auto &entry : directory.at("entries").as_array()) {
const auto path = entry.at("path").to_string();
if (path == "/self" || path == "/self/") {
if (path == self_path || path == self_path_slash) {
has_special_entries = true;
} else {
has_regular_entries = true;
Expand All @@ -339,7 +343,7 @@ inline auto make_file_manager(sourcemeta::core::HTMLWriter &writer,
writer.tbody();
for (const auto &entry : directory.at("entries").as_array()) {
const auto path = entry.at("path").to_string();
if (path != "/self" && path != "/self/") {
if (path != self_path && path != self_path_slash) {
make_file_manager_row(writer, entry);
}
}
Expand All @@ -357,7 +361,7 @@ inline auto make_file_manager(sourcemeta::core::HTMLWriter &writer,
writer.tbody();
for (const auto &entry : directory.at("entries").as_array()) {
const auto path = entry.at("path").to_string();
if (path == "/self" || path == "/self/") {
if (path == self_path || path == self_path_slash) {
make_file_manager_row(writer, entry);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/web/pages/directory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
#include <sourcemeta/one/metapack.h>
#include <sourcemeta/one/shared.h>

#include <cassert> // assert
#include <chrono> // std::chrono
#include <filesystem> // std::filesystem
#include <cassert> // assert
#include <chrono> // std::chrono

namespace sourcemeta::one {

Expand Down Expand Up @@ -38,7 +37,8 @@ auto GENERATE_WEB_DIRECTORY::handler(
html::make_breadcrumb(w, directory.at("breadcrumb"),
configuration.base_path);
html::make_directory_header(w, directory);
html::make_file_manager(w, directory);
html::make_file_manager(w, directory,
configuration.base_path);
});

const auto timestamp_end{std::chrono::steady_clock::now()};
Expand Down
8 changes: 4 additions & 4 deletions src/web/pages/index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
#include <sourcemeta/one/metapack.h>
#include <sourcemeta/one/shared.h>

#include <cassert> // assert
#include <chrono> // std::chrono
#include <filesystem> // std::filesystem
#include <cassert> // assert
#include <chrono> // std::chrono

namespace {

Expand Down Expand Up @@ -49,7 +48,8 @@ auto GENERATE_WEB_INDEX::handler(
html::make_page(writer, configuration, canonical, title, description,
[&](sourcemeta::core::HTMLWriter &w) {
make_hero(w, configuration);
html::make_file_manager(w, directory);
html::make_file_manager(w, directory,
configuration.base_path);
});

const auto timestamp_end{std::chrono::steady_clock::now()};
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/html/hurl/html.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ xpath "string(/html/head/title)" == "Sourcemeta Schemas"
xpath "count(//script[not(contains(@src, '?v='))])" == 0
xpath "count(//link[@rel='stylesheet' and not(contains(@href, '?v='))])" == 0
xpath "boolean(//footer//small[contains(., '{{edition}}')])" == true
xpath "boolean(//h6[contains(text(), 'Special directories')])" == true
xpath "boolean(//h6[contains(text(), 'Special directories')]/following-sibling::table[1]//a[@href='/self/'])" == true
xpath "count(//h6[contains(text(), 'Special directories')]/preceding-sibling::table//a[@href='/self/'])" == 0
header "Access-Control-Allow-Origin" not exists

# This is a Safari Accept header
Expand Down
38 changes: 38 additions & 0 deletions test/e2e/html/playwright/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { test, expect } from '@playwright/test';

test.describe('Home page directory listing', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});

test('renders a "Special directories" heading', async ({ page }) => {
const heading = page.getByRole('heading', { name: 'Special directories' });
await expect(heading).toBeVisible();
});

test('lists /self under the special directories table', async ({ page }) => {
const specialTable = page.locator(
'h6:has-text("Special directories") + table');
const selfLink = specialTable.locator('a[href="/self/"]');
await expect(selfLink).toBeVisible();
});

test('does not list /self in the regular directories table',
async ({ page }) => {
const regularTable = page.locator('table').first();
const selfLink = regularTable.locator('a[href="/self/"]');
await expect(selfLink).toHaveCount(0);
});

test('lists /test in the regular directories table, not the special one',
async ({ page }) => {
const regularTable = page.locator('table').first();
const testLink = regularTable.locator('a[href="/test/"]');
await expect(testLink).toBeVisible();

const specialTable = page.locator(
'h6:has-text("Special directories") + table');
const testInSpecial = specialTable.locator('a[href="/test/"]');
await expect(testInSpecial).toHaveCount(0);
});
});
9 changes: 9 additions & 0 deletions test/e2e/path/hurl/html.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
GET {{base}}/v1/catalog
Accept: text/html
HTTP 200
Content-Type: text/html
[Asserts]
xpath "string(/html/head/title)" == "Sourcemeta Schemas"
xpath "boolean(//h6[contains(text(), 'Special directories')])" == true
xpath "boolean(//h6[contains(text(), 'Special directories')]/following-sibling::table[1]//a[@href='/v1/catalog/self/'])" == true
xpath "count(//h6[contains(text(), 'Special directories')]/preceding-sibling::table//a[@href='/v1/catalog/self/'])" == 0
24 changes: 24 additions & 0 deletions test/e2e/path/playwright/navigation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ test.describe('Navigation with base path', () => {
await expect(page).toHaveURL(new RegExp(`${BASE_PATH}/example/`));
});

test('renders a "Special directories" heading on the root page',
async ({ page }) => {
await page.goto(BASE_PATH);
const heading = page.getByRole('heading', { name: 'Special directories' });
await expect(heading).toBeVisible();
});

test('lists /self under the special directories table on the root page',
async ({ page }) => {
await page.goto(BASE_PATH);
const specialTable = page.locator(
'h6:has-text("Special directories") + table');
const selfLink = specialTable.locator(`a[href="${BASE_PATH}/self/"]`);
await expect(selfLink).toBeVisible();
});

test('does not list /self in the regular directories table on the root page',
async ({ page }) => {
await page.goto(BASE_PATH);
const regularTable = page.locator('table').first();
const selfLink = regularTable.locator(`a[href="${BASE_PATH}/self/"]`);
await expect(selfLink).toHaveCount(0);
});

test('static assets load correctly', async ({ page }) => {
const responses = [];
page.on('response', (response) => {
Expand Down
Loading