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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

#### Profile-level

- **Liquibase**: Development changelog 78 sets a description, a metadata URL, and a dataset URL on folder Adreces (tree node 12339) in Visor IDEBarcelona. Gestió municipal (node 12338) stays empty ([sitmun-viewer-app#173](https://github.com/sitmun/sitmun-viewer-app/issues/173)).
- **Liquibase**: Development changelog 79 moves IDE Menorca folder download zips from `TNO_METAURL` to `TNO_DATAURL` and clears the metadata URL. Those zip names have no GeoNetwork record, so the catalog window shows the file under download data.
- **Liquibase**: PostgreSQL and Oracle changelog 27, and development changelog 74, add `PGI_OPTIONS` and format code `AUTO` ([#77](https://github.com/sitmun/sitmun-application-stack/issues/77)).
- **Liquibase**: Development changelog 75 seeds GetFeatureInfo fields on IDE genèric Menorca cartography 1304, Trams del camí de cavalls (`tu007rts_ccavalls`): route, kind, max easting, and website. Spanish and Catalan labels are translations; English is the stored default ([#77](https://github.com/sitmun/sitmun-application-stack/issues/77)).
- **Liquibase**: Development changelog 76 seeds seven GetFeatureInfo fields on cartography 4658, RPT Sòl Rústic (`OR007RPT_solrustic`): soil class, category, qualification, settlement names, area, and perimeter. Area and perimeter use two fraction digits.
Expand Down
110 changes: 110 additions & 0 deletions e2e/viewer/folder-catalog-info.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { expect, test, type Page } from '@playwright/test';
import {
APP_ID,
isBackendRequest,
NON_RADIO_ROOT_FOLDER_TITLE,
RADIO_FOLDER_TITLE,
readViewerCredentials,
TERRITORY_ID,
} from './fixtures';

const FOLDER_DB_ID = 1;
const FOLDER_DESCRIPTION = 'Carrers, números de portal i illes urbanes del municipi.';
const METADATA_URL = 'https://ide.example.cat/geonetwork/srv/cat/catalog.search#/metadata/adreces';
const DATASET_URL = 'https://ide.example.cat/descarrega/adreces.zip';

async function patchFolderInfo(page: Page): Promise<void> {
const login = await page.request.post('/backend/api/authenticate/admin', {
data: { username: 'admin', password: 'admin' },
});
expect(login.ok(), `admin login failed: ${login.status()}`).toBeTruthy();
const response = await page.request.patch(`/backend/api/tree-nodes/${FOLDER_DB_ID}`, {
headers: {
'X-SITMUN-Client': 'admin',
'Content-Type': 'application/merge-patch+json',
},
data: {
description: FOLDER_DESCRIPTION,
metadataURL: METADATA_URL,
datasetURL: DATASET_URL,
},
});
const body = (await response.json()) as Record<string, unknown>;
expect(response.ok(), `patch tree-node ${FOLDER_DB_ID} failed: ${response.status()} ${JSON.stringify(body)}`).toBeTruthy();
expect(body['description'], JSON.stringify(body)).toBe(FOLDER_DESCRIPTION);
expect(body['metadataURL']).toBe(METADATA_URL);
expect(body['datasetURL']).toBe(DATASET_URL);
}

async function openCatalog(page: Page): Promise<void> {
const credentials = await readViewerCredentials();
await page.goto('/auth/login');
await page.locator('input[name="username"]').fill(credentials.username);
await page.locator('input[name="password"]').fill(credentials.password);
await page.locator('form .login-button button').click();
await expect(page).toHaveURL(/\/user\/dashboard/);

const profile = page.waitForResponse(
(response) =>
isBackendRequest(response, `/config/client/profile/${APP_ID}/${TERRITORY_ID}`, 'GET') &&
response.ok(),
);
await page.goto(`/user/map/${APP_ID}/${TERRITORY_ID}`, { waitUntil: 'domcontentloaded' });
const profileResponse = await profile;
const profileBody = (await profileResponse.json()) as {
trees?: Array<{ nodes?: Record<string, Record<string, unknown>> }>;
};
const node = profileBody.trees
?.flatMap((tree) => Object.entries(tree.nodes ?? {}))
.find(([id]) => id === 'node/1')?.[1];
expect(node?.['description'], JSON.stringify(node)).toBe(FOLDER_DESCRIPTION);
expect(node?.['metadataURL']).toBe(METADATA_URL);
expect(node?.['datasetURL']).toBe(DATASET_URL);
await page.locator('#tc-slot-toc').waitFor({ state: 'attached', timeout: 90_000 });
await page.locator('.tc-tools-panel').evaluate((panel) => {
panel.classList.remove('tc-collapsed-right');
});
await expect(page.locator('.tc-tools-panel')).not.toHaveClass(/tc-collapsed-right/);
await expect(page.locator('#tc-slot-toc .tc-ctl-lcat-tree')).toBeVisible({ timeout: 30_000 });
}

function folderRow(page: Page, title: string) {
return page.locator('#tc-slot-toc li.tc-ctl-lcat-node').filter({
has: page.locator(':scope > span, :scope > .tc-ctl-lcat-node-title').filter({
hasText: new RegExp(`^${title}$`),
}),
});
}

test('folder information window follows the folder kind', async ({ page }) => {
await patchFolderInfo(page);
await openCatalog(page);

const filled = folderRow(page, NON_RADIO_ROOT_FOLDER_TITLE);
const empty = folderRow(page, RADIO_FOLDER_TITLE);
await expect(filled).toBeVisible();
await filled.getByRole('button', { name: /Expandir|Expand|Desplegar/i }).click();
await expect(empty).toBeVisible();

await expect(filled.locator(':scope > .tc-ctl-lcat-btn-info')).toBeVisible();
await expect(empty.locator(':scope > .tc-ctl-lcat-btn-info')).toHaveCount(0);

await page.screenshot({
path: '/tmp/sitmun-issue-173-implemented/01-catalog.png',
});

await filled.locator(':scope > .tc-ctl-lcat-btn-info').click();
const dialog = page.locator('#tc-slot-toc .tc-ctl-lcat-info');
await expect(dialog).toBeVisible();
await expect(dialog).toContainText(FOLDER_DESCRIPTION);
await expect(dialog.locator('a.tc-file-link').nth(0)).toHaveAttribute('href', METADATA_URL);
await expect(dialog.locator('a.tc-file-link').nth(1)).toHaveAttribute('href', DATASET_URL);
await expect(dialog).toContainText(
/Descripció del grup de capes|Descripción del grupo de capas|Layer group description/,
);
await expect(dialog).not.toContainText(/ID de la capa|Layer ID|Identificador de capa/);

await page.screenshot({
path: '/tmp/sitmun-issue-173-implemented/02-folder-window.png',
});
});
2 changes: 1 addition & 1 deletion playwright.viewer.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default defineConfig({
},
{
name: 'viewer-catalog',
testMatch: /layer-catalog\.spec\.ts/,
testMatch: /(?:layer-catalog|folder-catalog-info)\.spec\.ts/,
dependencies: ['viewer-setup'],
use: { ...devices['Desktop Chrome'] },
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
databaseChangeLog:
- changeSet:
id: 78-dev-folder-metadata-adreces
author: sitmun
context: dev
dbms: h2,postgresql,oracle
comment: >
Visor IDEBarcelona (application 15, tree 37). Folder Adreces (node 12339)
gets a description, a metadata URL, and a dataset URL so the viewer
catalog can open the folder information window. Gestió municipal
(node 12338) stays empty and has no button.
preConditions:
- onFail: MARK_RAN
sqlCheck:
expectedResult: 1
sql: >
SELECT CASE
WHEN (SELECT COUNT(*) FROM STM_TREE_NOD
WHERE TNO_ID = 12339
AND TNO_NAME = 'Adreces'
AND TNO_METAURL IS NULL) = 1
THEN 1 ELSE 0 END
changes:
- sql:
sql: |
UPDATE STM_TREE_NOD
SET TNO_ABSTRACT = 'Carrers, números de portal i illes urbanes del municipi.',
TNO_METAURL = 'https://www.icgc.cat/ca/Geoinformacio-i-mapes/Geoinformacio/Geoinformacio-de-referencia',
TNO_DATAURL = 'https://www.icgc.cat/ca/Descarregues'
WHERE TNO_ID = 12339;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
databaseChangeLog:
- changeSet:
id: 79-dev-folder-download-urls
author: sitmun
context: dev
dbms: h2,postgresql,oracle
comment: >
IDE Menorca folder nodes store a descarregues zip in TNO_METAURL and
leave TNO_DATAURL empty, so the catalog window shows a ZIP under
metadata. Those zip names have no GeoNetwork record. Move the zip to
the dataset URL and clear the metadata URL.
preConditions:
- onFail: MARK_RAN
sqlCheck:
expectedResult: 1
sql: >
SELECT CASE
WHEN (SELECT COUNT(*) FROM STM_TREE_NOD
WHERE TNO_DATAURL IS NULL
AND TNO_METAURL LIKE 'https://ide.cime.es/descarregues/%.zip') > 0
THEN 1 ELSE 0 END
changes:
- sql:
sql: |
UPDATE STM_TREE_NOD
SET TNO_DATAURL = TNO_METAURL,
TNO_METAURL = NULL
WHERE TNO_DATAURL IS NULL
AND TNO_METAURL LIKE 'https://ide.cime.es/descarregues/%.zip';
2 changes: 2 additions & 0 deletions profiles/development/backend/liquibase/master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@
<include file="changelog/75_dev_feature_info_fields.yaml" relativeToChangelogFile="true"/>
<include file="changelog/76_dev_sol_rustic_feature_info_fields.yaml" relativeToChangelogFile="true"/>
<include file="changelog/77_dev_estades_feature_info_fields.yaml" relativeToChangelogFile="true"/>
<include file="changelog/78_dev_folder_metadata_adreces.yaml" relativeToChangelogFile="true"/>
<include file="changelog/79_dev_folder_download_urls.yaml" relativeToChangelogFile="true"/>
</databaseChangeLog>
Loading