diff --git a/PLAN.md b/PLAN.md index 9da2d93..f302dba 100644 --- a/PLAN.md +++ b/PLAN.md @@ -739,8 +739,8 @@ Po ukończeniu zadania agent zmienia jego status w liście poniżej i dopisuje j - [x] T9 Person: title/pwzNumber - [x] T10 PwzRegistrySource - [x] T11 Organization/Company rekordy + round-trip -- [ ] T12 GraphLoader: Organization/Company [NEO4J] -- [ ] T13 GraphValidator: konflikt interesów [NEO4J] +- [~] T12 GraphLoader: Organization/Company [NEO4J] (skipped: Docker API version mismatch - testcontainers docker-java client v1.32, min 1.44) +- [~] T13 GraphValidator: konflikt interesow [NEO4J] (skipped: Docker API too old — same cause as T6) **Dziennik (data — zadanie — wynik):** - 2026-07-07 — T1 — Deduplicator compile fix + unit tests [checkpoint] (commit 38a93d0) diff --git a/szpitale-graph/local-agent-progress.json b/szpitale-graph/local-agent-progress.json index b5b11ff..d35b07d 100644 --- a/szpitale-graph/local-agent-progress.json +++ b/szpitale-graph/local-agent-progress.json @@ -109,19 +109,19 @@ "id": "T12", "title": "GraphLoader: Organization/Company", "tag": "NEO4J", - "status": "todo", - "startedAt": null, - "finishedAt": null, - "note": "Ladowanie :Organization/:Company + relacje CZLONEK_ORGANIZACJI/POWIAZANA_Z/POWIAZANY_Z_FIRMA (PLAN.md 5.4, T12)." + "status": "skipped", + "startedAt": "2026-07-08T23:25:00Z", + "finishedAt": "2026-07-08T23:38:00Z", + "note": "Docker API version mismatch: testcontainers docker-java client v1.32, min 1.44. Production code (GraphLoader GraphSchema) committed separately." }, { "id": "T13", "title": "GraphValidator: konflikt interesow", "tag": "NEO4J", - "status": "todo", + "status": "skipped", "startedAt": null, - "finishedAt": null, - "note": "Zapytanie: osoby w organie szpitala z powiazaniem biznesowym (PLAN.md 5.6, T13)." + "finishedAt": "2026-07-08T23:38:00Z", + "note": "Docker API too old (same reason as T12/T6/T7)." } ] } \ No newline at end of file diff --git a/szpitale-graph/src/test/java/com/developx/szpitale/load/GraphLoaderOrganizationIT.java b/szpitale-graph/src/test/java/com/developx/szpitale/load/GraphLoaderOrganizationIT.java new file mode 100644 index 0000000..7aa7875 --- /dev/null +++ b/szpitale-graph/src/test/java/com/developx/szpitale/load/GraphLoaderOrganizationIT.java @@ -0,0 +1,174 @@ +package com.developx.szpitale.load; + +import com.developx.szpitale.model.*; +import com.developx.szpitale.model.enums.LinkBasis; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.AuthTokens; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; +import org.testcontainers.containers.Neo4jContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +@Testcontainers +class GraphLoaderOrganizationIT { + + @Container + static Neo4jContainer neo4j = new Neo4jContainer<>("neo4j:5") + .withEnv("NEO4JLABS_PLUGINS", "['apoc']") + .withEnv("NEO4J_apoc_export_file_enabled", "true") + .withEnv("NEO4J_apoc_import_file_enabled", "true") + .withEnv("NEO4J_apoc_import_file_use__neo4j__config", "true"); + + static Driver driver; + + @BeforeAll + static void setupDriver() { + driver = org.neo4j.driver.GraphDatabase.driver( + neo4j.getBoltUrl(), + AuthTokens.basic("neo4j", "password")); + } + + @Test + void load_organizationAndCompany_nodesCreatedWithLinks() { + GraphSchema schema = new GraphSchema(driver); + schema.createConstraints(); + + Organization org = new Organization( + "org:test-fundacja", + "Test Fundacja", + "0000111222", + null, + List.of("https://example.org/fundacja") + ); + + Company company = new Company( + "company:test-sp-zoo", + "Test Sp. z o.o.", + "0000333444", + "1234567890", + null, + List.of("https://example.org/company") + ); + + Person person = new Person( + "person:test-osoba", + "Test Osoba", + "Test Osoba", + List.of(), + List.of("https://example.org/person"), + null, null + ); + + PersonOrganizationLink pol = new PersonOrganizationLink( + "person:test-osoba", + "org:test-fundacja", + "Czonek Zarzadu", + LinkBasis.KRS, + List.of("https://example.org/link") + ); + + PersonCompanyLink pcl = new PersonCompanyLink( + "person:test-osoba", + "company:test-sp-zoo", + "Wspolnik", + LinkBasis.NIP, + List.of("https://example.org/link2") + ); + + OrganizationLink orgLink = new OrganizationLink( + "org:test-fundacja", + "org:inna-fundacja", + LinkBasis.NIP, + "wspolny nip", + List.of("https://example.org/link3") + ); + + CanonicalDataset dataset = new CanonicalDataset( + "1.0", "test", + java.time.LocalDateTime.now(), + List.of(), + List.of(person), + List.of(), List.of(), List.of(), + List.of(org), + List.of(company), + List.of(pol), + List.of(orgLink), + List.of(pcl) + ); + + GraphLoader loader = new GraphLoader(driver); + GraphLoader.LoadStats stats = loader.load(List.of(dataset)); + + assertEquals(1, stats.organizationCount); + assertEquals(1, stats.companyCount); + assertEquals(1, stats.personOrganizationLinkCount); + assertEquals(1, stats.organizationLinkCount); + assertEquals(1, stats.personCompanyLinkCount); + + try (Session session = driver.session()) { + var orgResult = session.run( + "MATCH (o:Organization {id: 'org:test-fundacja'}) RETURN o.name AS name").list(); + assertFalse(orgResult.isEmpty()); + assertEquals("Test Fundacja", orgResult.get(0).get("name").asString()); + + var compResult = session.run( + "MATCH (c:Company {id: 'company:test-sp-zoo'}) RETURN c.name AS name").list(); + assertFalse(compResult.isEmpty()); + assertEquals("Test Sp. z o.o.", compResult.get(0).get("name").asString()); + + var polResult = session.run( + "MATCH (p:Person {id: 'person:test-osoba'})-" + + "[:CZLONEK_ORGANIZACJI]->(o:Organization) " + + "RETURN o.id AS orgId").list(); + assertFalse(polResult.isEmpty()); + assertEquals("org:test-fundacja", polResult.get(0).get("orgId").asString()); + + var pclResult = session.run( + "MATCH (p:Person {id: 'person:test-osoba'})-" + + "[:POWIAZANY_Z_FIRMA]->(c:Company) " + + "RETURN c.id AS compId").list(); + assertFalse(pclResult.isEmpty()); + assertEquals("company:test-sp-zoo", pclResult.get(0).get("compId").asString()); + + var orgLinkResult = session.run( + "MATCH (a:Organization {id: 'org:test-fundacja'})-" + + "[:POWIAZANA_Z]->(b:Organization) " + + "RETURN b.id AS toId").list(); + assertFalse(orgLinkResult.isEmpty()); + assertEquals("org:inna-fundacja", orgLinkResult.get(0).get("toId").asString()); + } + } + + @Test + void schema_constraints_created() { + GraphSchema schema = new GraphSchema(driver); + schema.createConstraints(); + + try (Session session = driver.session()) { + var result = session.run("SHOW CONSTRAINTS"); + int count = 0; + boolean hasOrgConstraint = false, hasCompConstraint = false; + while (result.hasNext()) { + count++; + var record = result.next(); + String constraintName = record.get("name").asString(); + if (constraintName.contains("org_id")) { + hasOrgConstraint = true; + } + if (constraintName.contains("company_id")) { + hasCompConstraint = true; + } + } + assertTrue(count > 0, "Should have constraints: found " + count); + assertTrue(hasOrgConstraint, "Organization constraint should exist"); + assertTrue(hasCompConstraint, "Company constraint should exist"); + } + } +} diff --git a/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst index 3f7a7af..5c1e3aa 100644 --- a/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +++ b/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -1,3 +1,4 @@ +com/developx/szpitale/load/GraphLoaderOrganizationIT.class com/developx/szpitale/ingest/OrganizationCompanyRoundTripTest.class com/developx/szpitale/ingest/source/PwzRegistrySourceTest.class com/developx/szpitale/ingest/normalize/NameNormalizerTest.class diff --git a/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst index 84c3586..d4a1d18 100644 --- a/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +++ b/szpitale-graph/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -5,4 +5,5 @@ /home/kruszewskia/Workspace/Private/Szpitale-graph/szpitale-graph/src/test/java/com/developx/szpitale/ingest/source/MarkdownRegistrySourceTest.java /home/kruszewskia/Workspace/Private/Szpitale-graph/szpitale-graph/src/test/java/com/developx/szpitale/ingest/source/PwzRegistrySourceTest.java /home/kruszewskia/Workspace/Private/Szpitale-graph/szpitale-graph/src/test/java/com/developx/szpitale/load/CanonicalRoundTripTest.java +/home/kruszewskia/Workspace/Private/Szpitale-graph/szpitale-graph/src/test/java/com/developx/szpitale/load/GraphLoaderOrganizationIT.java /home/kruszewskia/Workspace/Private/Szpitale-graph/szpitale-graph/src/test/java/com/developx/szpitale/model/PersonTest.java diff --git a/szpitale-graph/target/surefire-reports/TEST-com.developx.szpitale.load.GraphLoaderOrganizationIT.xml b/szpitale-graph/target/surefire-reports/TEST-com.developx.szpitale.load.GraphLoaderOrganizationIT.xml new file mode 100644 index 0000000..54c00df --- /dev/null +++ b/szpitale-graph/target/surefire-reports/TEST-com.developx.szpitale.load.GraphLoaderOrganizationIT.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/szpitale-graph/target/surefire-reports/com.developx.szpitale.load.GraphLoaderOrganizationIT.txt b/szpitale-graph/target/surefire-reports/com.developx.szpitale.load.GraphLoaderOrganizationIT.txt new file mode 100644 index 0000000..8632a3f --- /dev/null +++ b/szpitale-graph/target/surefire-reports/com.developx.szpitale.load.GraphLoaderOrganizationIT.txt @@ -0,0 +1,23 @@ +------------------------------------------------------------------------------- +Test set: com.developx.szpitale.load.GraphLoaderOrganizationIT +------------------------------------------------------------------------------- +Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.265 s <<< FAILURE! -- in com.developx.szpitale.load.GraphLoaderOrganizationIT +com.developx.szpitale.load.GraphLoaderOrganizationIT -- Time elapsed: 0.265 s <<< ERROR! +java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration + at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$7(DockerClientProviderStrategy.java:274) + at java.base/java.util.Optional.orElseThrow(Optional.java:403) + at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:265) + at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:154) + at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:196) + at org.testcontainers.DockerClientFactory$1.getDockerClient(DockerClientFactory.java:108) + at com.github.dockerjava.api.DockerClientDelegate.authConfig(DockerClientDelegate.java:109) + at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:321) + at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.start(TestcontainersExtension.java:276) + at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.access$200(TestcontainersExtension.java:263) + at org.testcontainers.junit.jupiter.TestcontainersExtension.lambda$null$4(TestcontainersExtension.java:83) + at org.testcontainers.junit.jupiter.TestcontainersExtension.lambda$startContainers$5(TestcontainersExtension.java:83) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1604) + at org.testcontainers.junit.jupiter.TestcontainersExtension.startContainers(TestcontainersExtension.java:83) + at org.testcontainers.junit.jupiter.TestcontainersExtension.beforeAll(TestcontainersExtension.java:57) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1604) + diff --git a/szpitale-graph/target/test-classes/com/developx/szpitale/load/GraphLoaderOrganizationIT.class b/szpitale-graph/target/test-classes/com/developx/szpitale/load/GraphLoaderOrganizationIT.class new file mode 100644 index 0000000..f75d5eb Binary files /dev/null and b/szpitale-graph/target/test-classes/com/developx/szpitale/load/GraphLoaderOrganizationIT.class differ