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
8 changes: 8 additions & 0 deletions e2e/content-pages.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ test.describe('Content pages render backend data', () => {
await expect(page.locator('body')).not.toContainText('Loading', { timeout: LOAD });
});

test("an icon's own page shows that icon, by its id", async ({ page }) => {
// /search/icon/{id}: the one icon, as a link to it opens it.
await page.goto('/community/icon-lib/R-ICO-012449');
await expect(page.locator('.detail-stid')).toHaveText('R-ICO-012449', { timeout: LOAD });
await expect(page.locator('.detail-summation')).not.toBeEmpty();
await expect(page.locator('.detail-preview img')).toBeVisible();
});

test('a CMS article page renders its body', async ({ page }) => {
// page.component.ts fetches the compiled content JSON and renders markdown.
await page.goto('/documentation/userguide');
Expand Down
1 change: 1 addition & 0 deletions e2e/har/1f4df14a0a07f02f5d3570058da470c7d43b7683.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dbId":"012449","stId":"R-ICO-012449","id":"R-ICO-012449","name":"ASPPs","type":"Icon","exactType":"Icon","species":["Homo sapiens"],"summation":"Family of Apoptosis-stimulating of p53 proteins","hasReferenceEntity":false,"hasEHLD":false,"iconName":"ASPPs","iconCategories":["protein"],"iconCuratorName":"Marija Orlic-Milacic","iconCuratorOrcidId":"0000-0002-3218-5631","iconDesignerName":"Cristoffer Sevilla","iconDesignerUrl":"https://graphsolutions.co.uk","iconReferences":["Q96KQ4","UNIPROT:Q96KQ4","Q13625","UNIPROT:Q13625"],"iconPhysicalEntities":[{"stId":"R-HSA-6799775","type":"ReferenceGeneProduct","name":"PPP1R13B","compartments":"nucleoplasm","displayName":"PPP1R13B [nucleoplasm]"},{"stId":"uniprot:Q96KQ4","type":"ReferenceGeneProduct","name":"PPP1R13B","compartments":"null","displayName":"PPP1R13B [null]"},{"stId":"R-HSA-6799780","type":"ReferenceGeneProduct","name":"TP53BP2","compartments":"nucleoplasm","displayName":"TP53BP2 [nucleoplasm]"},{"stId":"uniprot:Q13625","type":"ReferenceGeneProduct","name":"TP53BP2","compartments":"null","displayName":"TP53BP2 [null]"}],"iconEhlds":["R-HSA-5633007"],"icon":true}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"log":{"version":"1.2","entries":[{"request":{"method":"GET","url":"http://localhost:4330/ContentService/search/icon/facet"},"response":{"status":200,"headers":[{"name":"Vary","value":"Origin"},{"name":"access-control-allow-origin","value":"*"},{"name":"connection","value":"close"},{"name":"content-length","value":"389"},{"name":"content-type","value":"application/json;charset=UTF-8"},{"name":"date","value":"Tue, 27 Oct 2026 00:55:12 GMT"}],"content":{"mimeType":"application/json;charset=UTF-8","_file":"7fee71d851dbc0883e01198a2731b5c3b66c49d3.json"}}},{"request":{"method":"GET","url":"http://localhost:4330/ContentService/search/icon/R-ICO-012449"},"response":{"status":200,"headers":[{"name":"Vary","value":"Origin"},{"name":"access-control-allow-origin","value":"*"},{"name":"connection","value":"close"},{"name":"content-length","value":"1132"},{"name":"content-type","value":"application/json;charset=UTF-8"},{"name":"date","value":"Tue, 27 Oct 2026 00:55:12 GMT"}],"content":{"mimeType":"application/json;charset=UTF-8","_file":"1f4df14a0a07f02f5d3570058da470c7d43b7683.json"}}},{"request":{"method":"GET","url":"http://localhost:4330/ContentService/data/species/main"},"response":{"status":200,"headers":[{"name":"Vary","value":"Origin"},{"name":"access-control-allow-origin","value":"*"},{"name":"connection","value":"close"},{"name":"content-length","value":"3237"},{"name":"content-type","value":"application/json;charset=UTF-8"},{"name":"date","value":"Tue, 27 Oct 2026 00:55:12 GMT"}],"content":{"mimeType":"application/json;charset=UTF-8","_file":"b1aee4d715fbe327136decb78e604b0ab8464ced.json"}}},{"request":{"method":"GET","url":"http://localhost:4330/ContentService/data/database/version"},"response":{"status":200,"headers":[{"name":"Vary","value":"Origin"},{"name":"access-control-allow-origin","value":"*"},{"name":"connection","value":"close"},{"name":"content-length","value":"2"},{"name":"content-type","value":"text/plain;charset=UTF-8"},{"name":"date","value":"Tue, 27 Oct 2026 00:55:12 GMT"}],"content":{"mimeType":"text/plain;charset=UTF-8","_file":"812ed4562d3211363a7b813aa9cd2cf042b63bb2.txt"}}}]}}
2 changes: 1 addition & 1 deletion specs/013-server-types/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Each task: rename to `.ts`, update imports, file names that name it (R3 list), f

## Phase 4: The answers the services write (US3)

- [ ] T019 [US3] Where the site reads the same answer (spec 012's call table), the content service writes it through the site's model type, one definition; show a field renamed in the shared type failing in both. Done for the contents lists (toc, doi, contributors), the schema attribute and referral tables and the schema model (#561). Schema min and instance referrers too (#562), with the site's `SimpleDatabaseObject` corrected to what is written (no `stId` on an InstanceEdit or Species). The diagram and species-overview flags and the PSICQUIC resources too (#563); spellcheck and suggest are `string[]` on both sides already. Then (#676, replacing #675) the pathway citation; the facets and icon facets; and locationsInPWB -- the last two decided 26 Oct 2026 to follow what is written, measured where it mattered. The facets: the site's `FacetCount` and `IconCategory` leave the name optional and `FacetResponse` its four facets, as the service (and Java) leave out an unnamed count and a facet Solr did not count; the site's readers show only named counts; node writes them as the site's `FacetResponse` and `IconFacetResponse`, its `FacetContainer` being the site's `FacetCount`. locationsInPWB: over 179 recorded answers (1,694 nodes) `diagram` is never written and `species` is absent on species-less objects (56), so the site's `PathwayBrowserNode` drops `diagram` and makes `species` optional; stId, name, type and url are in every one and stay required; node writes them through the site's type and, as Java does, leaves out one a node lacks rather than failing (never seen). The icon library's `iconCategoriesFacet` is optional too, as the search facets are. Then (#677) the interactors (the molecules' details, the enhanced details, withEntities): their writers keep writing JSON text, member by member, for Java's numbers, but `nonEmptyJson<T>` now checks each member's name and value against the site's type T -- a field renamed or retyped there fails here. It does not check that a required member is written (any value may be left out) or what JSON already written holds (the nested lists, checked only by their own writers). The site's `CustomInteraction` gains the `url` it is written with: the recorded answers' 89 known problems on that route are 0 now. Then (#678) the person event lists: over the recorded answers (8 distinct requests, 14 events) each carries the edit's dateTime and authorDbId and its labels, and one a DOI, which the site's `SimpleEvent` lacked; it has them now, node writes each event as that type, and the route's 31 known problems are 0. Left: the icon entry (the search family's entry, built field by field from Solr's documents with nothing typed). (Likewise, a PSICQUIC service whose registry name is empty is written without the `name` the site's `PsicquicResource` requires, as Java writes it; the real registry has none.)
- [x] T019 [US3] Where the site reads the same answer (spec 012's call table), the content service writes it through the site's model type, one definition; show a field renamed in the shared type failing in both. Done for the contents lists (toc, doi, contributors), the schema attribute and referral tables and the schema model (#561). Schema min and instance referrers too (#562), with the site's `SimpleDatabaseObject` corrected to what is written (no `stId` on an InstanceEdit or Species). The diagram and species-overview flags and the PSICQUIC resources too (#563); spellcheck and suggest are `string[]` on both sides already. Then (#676, replacing #675) the pathway citation; the facets and icon facets; and locationsInPWB -- the last two decided 26 Oct 2026 to follow what is written, measured where it mattered. The facets: the site's `FacetCount` and `IconCategory` leave the name optional and `FacetResponse` its four facets, as the service (and Java) leave out an unnamed count and a facet Solr did not count; the site's readers show only named counts; node writes them as the site's `FacetResponse` and `IconFacetResponse`, its `FacetContainer` being the site's `FacetCount`. locationsInPWB: over 179 recorded answers (1,694 nodes) `diagram` is never written and `species` is absent on species-less objects (56), so the site's `PathwayBrowserNode` drops `diagram` and makes `species` optional; stId, name, type and url are in every one and stay required; node writes them through the site's type and, as Java does, leaves out one a node lacks rather than failing (never seen). The icon library's `iconCategoriesFacet` is optional too, as the search facets are. Then (#677) the interactors (the molecules' details, the enhanced details, withEntities): their writers keep writing JSON text, member by member, for Java's numbers, but `nonEmptyJson<T>` now checks each member's name and value against the site's type T -- a field renamed or retyped there fails here. It does not check that a required member is written (any value may be left out) or what JSON already written holds (the nested lists, checked only by their own writers). The site's `CustomInteraction` gains the `url` it is written with: the recorded answers' 89 known problems on that route are 0 now. Then (#678) the person event lists: over the recorded answers (8 distinct requests, 14 events) each carries the edit's dateTime and authorDbId and its labels, and one a DOI, which the site's `SimpleEvent` lacked; it has them now, node writes each event as that type, and the route's 31 known problems are 0. The icon entry, the last left, went in with the search family's whole contract in spec 016 (T002–T014): the facets (#684), the entry and its typed writer (#689), its readers (#691, #697), the search answers (#703) and the single icon's recording (#704). The search routes' known problems are 0. (Likewise, a PSICQUIC service whose registry name is empty is written without the `name` the site's `PsicquicResource` requires, as Java writes it; the real registry has none.)
- [ ] T020 [US3] Answers only the services write: types beside the service.

---
Expand Down
4 changes: 2 additions & 2 deletions specs/016-api-contract/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ description: 'Tasks for spec 016: one API contract for the content service and t

- [x] T013 [US3] Write `ResultGroup<E>`, `GroupedResult` (with `numberOfGroups`), the diagram and species-overview result types and `IconResult` (with `rowCount` and `typeName`) in `projects/contract/search.ts`, and point their writers in `search-endpoints.ts` and `search-diagram-endpoints.ts`, and their readers, at them.
- Done in #703. The contract's `ResultGroup<Entry>`, `GroupedResult<Entry>`, `DiagramResult<Entry>`, `TargetResult` and `IconResult`, each taking its entry type as a named argument: the service writes them with its `WrittenEntry`, a reader reads them with the view. A group's `entries` is optional (an ungrouped page past the end has none) and so is its `typeName` (a group Solr names with nothing); the search page settles both once when the answer arrives (`ShownGroup`), and the pathway browser's search shows only named type facets, as the site's does. A target's empty term or resource is left out, so both are optional. A grouping without `matches` is skipped, as SolrJ's `QueryResponse.extractGroupedInfo` skips it (read from its bytecode, from #700's review): the first grouping that has its matches is read, and none is no result, Java's 500 (a spec of two groupings, the first without matches, fails on the first-grouping reading). The search routes' known problems are 0, the whole 12,164. From #697's review, the pathway browser's icon tooltip takes `iconName`, never highlighted.
- [ ] T014 [US3] Record an answer for `/search/icon/{id}` (already in `tools/api-types/calls.ts` as `IconEntry`, with a `gap`) through the e2e suite and remove the `gap` (record rewrites three HARs: check the diff). Type its writer.
- [ ] T015 [US3] Tick spec 013 T019 in `specs/013-server-types/tasks.md` with T002–T014's PR numbers.
- [x] T014 [US3] Record an answer for `/search/icon/{id}` (already in `tools/api-types/calls.ts` as `IconEntry`, with a `gap`) through the e2e suite and remove the `gap` (record rewrites three HARs: check the diff). Type its writer. — #704. `e2e/content-pages.spec.ts` opens `/community/icon-lib/R-ICO-012449`, recorded against beta's services (`CONTENT_NODE_TARGET` at its port): the single-icon answer holds to the contract's `IconEntry`, and a contract `iconName` made a number fails on it, so the check reads it.
- [x] T015 [US3] Tick spec 013 T019 in `specs/013-server-types/tasks.md` with T002–T014's PR numbers. — #704.

## Phase 5: User Story 1 - A change fails on both sides (P1)

Expand Down
2 changes: 1 addition & 1 deletion tools/api-types/calls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const CALLS: Call[] = [
{ file: `${WEB}/services/detail-data.service.ts`, method: 'fetchEnhancedData', http: 'GET', route: '/data/query/enhanced/v2/{id}', type: 'DatabaseObject', reads: 'T' },
{ file: `${WEB}/services/icon.service.ts`, method: 'getFacets', http: 'GET', route: '/search/icon/facet', type: 'IconFacetResponse' },
{ file: `${WEB}/services/icon.service.ts`, method: 'queryIcons', http: 'GET', route: '/search/icon/query', type: 'IconResult' },
{ file: `${WEB}/services/icon.service.ts`, method: 'getIcon', http: 'GET', route: '/search/icon/{id}', type: 'IconEntry', gap: 'the recordings never open one icon' },
{ file: `${WEB}/services/icon.service.ts`, method: 'getIcon', http: 'GET', route: '/search/icon/{id}', type: 'IconEntry' },
{ file: `${WEB}/services/search.service.ts`, method: 'search', http: 'GET', route: '/search/query', type: 'SearchResult' },
{ file: `${WEB}/services/search.service.ts`, method: 'getFacets', http: 'GET', route: '/search/facet_query', type: 'FacetResponse' },
{ file: `${WEB}/services/search.service.ts`, method: 'getAllFacets', http: 'GET', route: '/search/facet', type: 'FacetResponse', gap: 'the recordings always search with a query' },
Expand Down
Loading