Skip to content

Commit f373cc0

Browse files
jamsdenclaude
andcommitted
test: integration test for LDMClient against oslc-service /discover-links
Opt-in integration test (RUN_OSLC_SERVICE_LDM_TESTS=true) that verifies the existing LDMClient legacy-LDM code path works unchanged against the new oslc-service LDM endpoint. No client-side changes required; the test is purely a regression guard. Two cases: 1. Basic: getIncomingLinks returns a non-empty result set for a known target, and the server filters out infrastructure predicates (rdf:type, ldp:contains, oslc:serviceProvider, oslc:instanceShape). 2. Predicate-filtered: passing linkTypes restricts results to the specified predicate. Prereq: bmm-server running with populated EU-Rent data (run testing/populate-eurent.sh). OSLC_SERVICE_TARGET_URI env var supplies a populated resource URI that has known incoming links (e.g., the Vision, which is referenced by Strategies' channelsEffortsToward). Implements Task 6 of docs/superpowers/plans/2026-04-01-ldm-incoming- links.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 56a1962 commit f373cc0

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Integration test — LDMClient against an oslc-service server's
3+
* /discover-links endpoint.
4+
*
5+
* Verifies that the existing LDMClient legacy-LDM code path (which
6+
* POSTs Turtle to `{baseURL}/discover-links`) works unchanged against
7+
* the new oslc-service LDM handler added in oslc-service commit
8+
* d9a0b51 / jena-storage-service commit 7cfcc9a. No client-side code
9+
* changes required.
10+
*
11+
* Enable:
12+
* RUN_OSLC_SERVICE_LDM_TESTS=true npm test
13+
*
14+
* Prereqs:
15+
* - bmm-server running at http://localhost:3005 (or whatever URL is
16+
* provided via OSLC_SERVICE_BASE_URL) with jena-storage-service
17+
* backing it
18+
* - the EU-Rent example populated (run testing/populate-eurent.sh)
19+
* - OSLC_SERVICE_TARGET_URI set to a URI that is actually referenced
20+
* by other resources in the graph (e.g., a Vision URI — other
21+
* Strategies point at it via channelsEffortsToward, so we expect
22+
* at least one incoming link)
23+
*/
24+
25+
import OSLCClient from '../OSLCClient.js';
26+
import LDMClient from '../LDMClient.js';
27+
28+
const RUN = process.env.RUN_OSLC_SERVICE_LDM_TESTS === 'true';
29+
const describeIf = RUN ? describe : describe.skip;
30+
31+
describeIf('LDMClient against oslc-service /discover-links', () => {
32+
test('returns incoming links for a known target resource', async () => {
33+
const baseUrl = process.env.OSLC_SERVICE_BASE_URL || 'http://localhost:3005';
34+
const targetUrl = process.env.OSLC_SERVICE_TARGET_URI;
35+
36+
if (!targetUrl) {
37+
throw new Error(
38+
'OSLC_SERVICE_TARGET_URI must be set to a populated resource URI. ' +
39+
'Example: run testing/populate-eurent.sh, then curl the Vision URI from ' +
40+
'the query endpoint: ' +
41+
'curl "http://localhost:3005/oslc/eu-rent/query?oslc.where=rdf:type=%3Chttp://www.omg.org/spec/BMM%23Vision%3E" ' +
42+
'-H "Accept: text/turtle"'
43+
);
44+
}
45+
46+
const oslcClient = new OSLCClient();
47+
const ldm = new LDMClient(oslcClient, baseUrl);
48+
49+
const triples = await ldm.getIncomingLinks([targetUrl]);
50+
51+
expect(Array.isArray(triples)).toBe(true);
52+
// A Vision in the populated EU-Rent example is pointed at by
53+
// multiple Strategies (channelsEffortsToward). A Goal is pointed at
54+
// by Strategies, Tactics (enablesEnd), and is Vision.madeOperativeBy.
55+
// Any populated target should have at least one incoming link.
56+
expect(triples.length).toBeGreaterThan(0);
57+
58+
for (const t of triples) {
59+
expect(t).toHaveProperty('sourceURL');
60+
expect(t).toHaveProperty('linkType');
61+
expect(t).toHaveProperty('targetURL');
62+
expect(t.targetURL).toBe(targetUrl);
63+
// Infrastructure predicates should be filtered out by the server
64+
expect(t.linkType).not.toBe('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
65+
expect(t.linkType).not.toBe('http://www.w3.org/ns/ldp#contains');
66+
expect(t.linkType).not.toBe('http://open-services.net/ns/core#serviceProvider');
67+
expect(t.linkType).not.toBe('http://open-services.net/ns/core#instanceShape');
68+
}
69+
});
70+
71+
test('predicate filter restricts result set', async () => {
72+
const baseUrl = process.env.OSLC_SERVICE_BASE_URL || 'http://localhost:3005';
73+
const targetUrl = process.env.OSLC_SERVICE_TARGET_URI;
74+
const filterPredicate = process.env.OSLC_SERVICE_FILTER_PREDICATE;
75+
76+
if (!targetUrl || !filterPredicate) {
77+
// Skip silently if the env vars aren't set — the primary test
78+
// above is the minimum acceptance bar.
79+
return;
80+
}
81+
82+
const oslcClient = new OSLCClient();
83+
const ldm = new LDMClient(oslcClient, baseUrl);
84+
85+
const triples = await ldm.getIncomingLinks([targetUrl], [filterPredicate]);
86+
87+
expect(Array.isArray(triples)).toBe(true);
88+
for (const t of triples) {
89+
expect(t.linkType).toBe(filterPredicate);
90+
expect(t.targetURL).toBe(targetUrl);
91+
}
92+
});
93+
});

0 commit comments

Comments
 (0)