From f643db6118ca2ce2828f2d71afb752c6d0e6bb13 Mon Sep 17 00:00:00 2001 From: Artur Kruszewski Date: Wed, 8 Jul 2026 23:40:14 +0200 Subject: [PATCH] =?UTF-8?q?T12:=20GraphLoaderOrganizationIT=20(skipped:=20?= =?UTF-8?q?Docker=20API)=20=E2=80=94=20prod=20code=20already=20committed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PLAN.md | 4 +- szpitale-graph/local-agent-progress.json | 14 +- .../load/GraphLoaderOrganizationIT.java | 174 ++++++++++++++++++ .../default-testCompile/createdFiles.lst | 1 + .../default-testCompile/inputFiles.lst | 1 + ...zpitale.load.GraphLoaderOrganizationIT.xml | 93 ++++++++++ ...zpitale.load.GraphLoaderOrganizationIT.txt | 23 +++ .../load/GraphLoaderOrganizationIT.class | Bin 0 -> 8848 bytes 8 files changed, 301 insertions(+), 9 deletions(-) create mode 100644 szpitale-graph/src/test/java/com/developx/szpitale/load/GraphLoaderOrganizationIT.java create mode 100644 szpitale-graph/target/surefire-reports/TEST-com.developx.szpitale.load.GraphLoaderOrganizationIT.xml create mode 100644 szpitale-graph/target/surefire-reports/com.developx.szpitale.load.GraphLoaderOrganizationIT.txt create mode 100644 szpitale-graph/target/test-classes/com/developx/szpitale/load/GraphLoaderOrganizationIT.class 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 0000000000000000000000000000000000000000..f75d5eb7cdbfdfcb6a20a5eb0b5d21833229f3e8 GIT binary patch literal 8848 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 literal 0 HcmV?d00001