diff --git a/K6/api/building-blocks/register/index.js b/K6/api/building-blocks/register/index.js index fde6c852..7c5c459d 100644 --- a/K6/api/building-blocks/register/index.js +++ b/K6/api/building-blocks/register/index.js @@ -2,3 +2,4 @@ export { RemoveRevisorRoleFromEr } from "./remove-revisor-role-from-er.js"; export { AddRevisorRoleToErForOrg } from "./add-revisor-role-to-er-for-org.js"; export { GetRevisorCustomerIdentifiersForParty } from "./get-revisor-customer-identifiers-for-party.js"; export { LookUpPartyInRegister as LookupPartiesInRegister } from "./look-up-parties.js"; +export { SubmitErData } from "./submit-er-data.js"; diff --git a/K6/api/building-blocks/register/submit-er-data.js b/K6/api/building-blocks/register/submit-er-data.js new file mode 100644 index 00000000..26bcf5c9 --- /dev/null +++ b/K6/api/building-blocks/register/submit-er-data.js @@ -0,0 +1,29 @@ +import { check } from "k6"; +import { RegisterApiClient } from "../../../clients/authentication/index.js"; + +/** + * Posts a SubmitERDataBasic SOAP envelope to the ER update endpoint and checks + * that the response indicates successful processing. + * + * Credentials must be interpolated into the SOAP body before calling this function. + * + * @param {RegisterApiClient} registerClient + * @param {string} soapBody - Complete SOAP envelope with credentials already set + * @returns (string | ArrayBuffer | null) + */ +export function SubmitErData(registerClient, soapBody, label = "SubmitErData") { + const res = registerClient.SubmitErData(soapBody); + + const ok = check(res, { + [`${label} - status code MUST be 200`]: (r) => r.status === 200, + [`${label} - response contains OK_ER_DATA_PROCESSED`]: (r) => + r.body && r.body.includes("status=\"OK_ER_DATA_PROCESSED\""), + }); + + if (!ok) { + console.error(res.status); + console.error(res.body); + } + + return res; +} diff --git a/K6/api/tests/register/er-sync/README.md b/K6/api/tests/register/er-sync/README.md new file mode 100644 index 00000000..c4eede10 --- /dev/null +++ b/K6/api/tests/register/er-sync/README.md @@ -0,0 +1,25 @@ +# ER Sync Tests + +Verifies that data submitted to the Enhetsregisteret (ER) via SOAP is correctly synced to Altinn Register. Each test submits a **prep** state (creates the organization), then a **change**, and finally verifies the change is reflected in Register. + +## Running + +```bash +# Run all tests +k6 run run-all.js -e ENVIRONMENT=at22 -e BASE_URL=https://platform.at22.altinn.cloud \ + -e SOAP_ER_USERNAME= -e SOAP_ER_PASSWORD=

-e REGISTER_SUBSCRIPTION_KEY= + +# Stop after prep (seed state, inspect manually in portal) +k6 run change-styr.js -e STOP_AFTER_PREP=true +k6 run run-all.js -e STOP_AFTER_PREP=true +``` + +### Required environment variables + +| Variable | Description | +|---|---| +| `ENVIRONMENT` | Target environment, e.g. `at22`, `at23`, `tt02` | +| `BASE_URL` | Base URL for the Register API | +| `SOAP_ER_USERNAME` | Username for the ER SOAP endpoint | +| `SOAP_ER_PASSWORD` | Password for the ER SOAP endpoint | +| `REGISTER_SUBSCRIPTION_KEY` | Subscription key for the Register API | \ No newline at end of file diff --git a/K6/api/tests/register/er-sync/er-sync-summary.js b/K6/api/tests/register/er-sync/er-sync-summary.js new file mode 100644 index 00000000..5e66e051 --- /dev/null +++ b/K6/api/tests/register/er-sync/er-sync-summary.js @@ -0,0 +1,50 @@ +/** + * Custom k6 summary handler for ER sync tests. + * + * Outputs one line per testcase: + * ✅ testcase-name (all checks passed) + * ❌ testcase-name (one or more checks failed) + * - failing check name + * - another failing check name + */ + +function collectFailingChecks(group) { + const failing = []; + for (const c of group.checks || []) { + if (c.fails > 0) failing.push(c.name); + } + for (const child of group.groups || []) { + failing.push(...collectFailingChecks(child)); + } + return failing; +} + +export function handleSummary(data) { + const lines = ["\nER Sync Test Results", "=".repeat(40)]; + let passed = 0; + let failed = 0; + + const groups = (data.root_group.groups || []) + .filter((g) => g.name !== "Cleanup" && !g.name.startsWith("Verify -")) + .sort((a, b) => parseInt(a.name) - parseInt(b.name)); + + for (const group of groups) { + const failingChecks = collectFailingChecks(group); + + if (failingChecks.length === 0) { + lines.push(`✅ ${group.name}`); + passed++; + } else { + lines.push(`❌ ${group.name}`); + for (const name of failingChecks) { + lines.push(` ❌ ${name}`); + } + failed++; + } + } + + const total = passed + failed; + lines.push(`\n${passed}/${total} testcases passed\n`); + + return { stdout: lines.join("\n") }; +} diff --git a/K6/api/tests/register/er-sync/helper.js b/K6/api/tests/register/er-sync/helper.js new file mode 100644 index 00000000..3a820686 --- /dev/null +++ b/K6/api/tests/register/er-sync/helper.js @@ -0,0 +1,124 @@ +import { group, check, fail } from "k6"; +import { EnterpriseTokenGenerator, PlatformTokenGenerator } from "../../../../common-imports.js"; +import { AuthorizedPartiesClient, RegisterApiClient, RegisterLookupClient } from "../../../../clients/authentication/index.js"; +import { GetAuthorizedParties } from "../../../building-blocks/authentication/authorized-parties/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { retry } from "../../../../helpers.js"; + +for (const key of ["ENVIRONMENT", "BASE_URL", "SOAP_ER_USERNAME", "SOAP_ER_PASSWORD"]) { + if (!__ENV[key]) throw new Error(`Missing required env var: ${key}`); +} + +export function buildErSoapEnvelope(batchXml) { + return ` + + + + ${__ENV.SOAP_ER_USERNAME} + ${__ENV.SOAP_ER_PASSWORD} + + ${batchXml}]]> + + +`; +} + +export function createAuthorizedPartiesClient() { + const tokenOpts = new Map(); + tokenOpts.set("env", __ENV.ENVIRONMENT); + tokenOpts.set("ttl", 3600); + tokenOpts.set("scopes", "altinn:accessmanagement/authorizedparties.resourceowner"); + return new AuthorizedPartiesClient(__ENV.BASE_URL, new EnterpriseTokenGenerator(tokenOpts)); +} + +export function retryUntilHasAccess(apClient, fnr, orgNr, scenario) { + let result = null; + retry( + () => { + const parties = GetAuthorizedParties(apClient, "urn:altinn:person:identifier-no", fnr, { includeAltinn2: false, includePartiesViaKeyRoles: true }); + if (!Array.isArray(parties)) return false; + const hasAccess = parties.some((p) => p.organizationNumber === orgNr || p.orgNumber === orgNr); + if (hasAccess) result = parties; + return hasAccess; + }, + { retries: 15, intervalSeconds: 20, testscenario: scenario }, + ); + return result; +} + +export function retryUntilNoAccess(apClient, fnr, orgNr, scenario) { + let result = null; + retry( + () => { + const parties = GetAuthorizedParties(apClient, "urn:altinn:person:identifier-no", fnr, { includeAltinn2: false, includePartiesViaKeyRoles: true }); + if (!Array.isArray(parties)) return false; + const noAccess = !parties.some((p) => p.organizationNumber === orgNr || p.orgNumber === orgNr); + if (noAccess) result = parties; + return noAccess; + }, + { retries: 15, intervalSeconds: 20, testscenario: scenario }, + ); + return result; +} + +function pollOrganization(lookupClient, orgNr) { + const res = lookupClient.LookupParties("party,person,org,user,si,sysuser", { data: [`urn:altinn:organization:identifier-no:${orgNr}`] }); + if (res.status !== 200) return null; + const body = JSON.parse(res.body); + return body.data[0] || null; +} + +export function runErSyncTestcase(scenarioName, prepXml, changeXml, orgNr, verifyChecks = {}, { stopAfterPrep = false } = {}) { + const tokenOpts = new Map(); + tokenOpts.set("env", __ENV.ENVIRONMENT); + tokenOpts.set("ttl", 3600); + + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + const lookupClient = new RegisterLookupClient(__ENV.BASE_URL, new PlatformTokenGenerator(tokenOpts)); + + group(scenarioName, () => { + group("Prep - submit organization to ER", () => { + const res = SubmitErData(apiClient, prepXml, "Prep"); + if (res.status !== 200) fail(`[${scenarioName}] Prep failed with status ${res.status} — aborting test`); + }); + + group("Prep - verify organization is visible in Register", () => { + let prepParty = null; + retry( + () => { + const party = pollOrganization(lookupClient, orgNr); + if (!party) return false; + prepParty = party; + return true; + }, + { retries: 15, intervalSeconds: 20, testscenario: `${scenarioName} - prep` }, + ); + if (prepParty) { + check(prepParty, { "Prep - org is visible in Register": (p) => p.organizationIdentifier === orgNr }); + } + }); + + if (stopAfterPrep || __ENV.STOP_AFTER_PREP === "true") return; + + group("Change - submit ER update", () => { + SubmitErData(apiClient, changeXml, "Change"); + }); + + group("Verify - Register reflects change", () => { + let verifiedParty = null; + retry( + () => { + const party = pollOrganization(lookupClient, orgNr); + if (!party || !Object.values(verifyChecks).every((fn) => fn(party))) return false; + verifiedParty = party; + return true; + }, + { retries: 15, intervalSeconds: 20, testscenario: `${scenarioName} - verify` }, + ); + if (verifiedParty) { + check(verifiedParty, verifyChecks); + } + }); + + }); +} diff --git a/K6/api/tests/register/er-sync/run-all.js b/K6/api/tests/register/er-sync/run-all.js new file mode 100644 index 00000000..6308123d --- /dev/null +++ b/K6/api/tests/register/er-sync/run-all.js @@ -0,0 +1,38 @@ +import { nameShortChange } from "./testcase_1_change_org_name.js"; +import { addMedl } from "./testcase_2_add_styremedlem.js"; +import { removeMedl } from "./testcase_3_remove_styremedlem.js"; +import { daglChange } from "./testcase_4_replace_daglig_leder.js"; +import { styrChange } from "./testcase_5_replace_styreleder.js"; +import { fadrChange } from "./testcase_6_change_forretningsadresse.js"; +import { contactChange } from "./testcase_7_update_contact_info.js"; +import { addFmva } from "./testcase_8_add_frivillig_mva.js"; +import { kasteStyret } from "./testcase_9_kaste_styret.js"; + +/** + * @file run-all.js + * @description Runs all ER sync testcases as named scenarios. + * + * k6 run run-all.js \ + * -e ENVIRONMENT=at22 -e BASE_URL=https://platform.at22.altinn.cloud \ + * -e SOAP_ER_USERNAME= -e SOAP_ER_PASSWORD=

\ + * -e REGISTER_SUBSCRIPTION_KEY= + */ + +export const options = { + scenarios: { + "testcase-1-change-org-name": { executor: "shared-iterations", exec: "nameShortChange", vus: 1, iterations: 1 }, + "testcase-2-add-styremedlem": { executor: "shared-iterations", exec: "addMedl", vus: 1, iterations: 1 }, + "testcase-3-remove-styremedlem": { executor: "shared-iterations", exec: "removeMedl", vus: 1, iterations: 1 }, + "testcase-4-replace-daglig-leder": { executor: "shared-iterations", exec: "daglChange", vus: 1, iterations: 1 }, + "testcase-5-replace-styreleder": { executor: "shared-iterations", exec: "styrChange", vus: 1, iterations: 1 }, + "testcase-6-change-forretningsadresse":{ executor: "shared-iterations", exec: "fadrChange", vus: 1, iterations: 1 }, + "testcase-7-update-contact-info": { executor: "shared-iterations", exec: "contactChange", vus: 1, iterations: 1 }, + "testcase-8-add-frivillig-mva": { executor: "shared-iterations", exec: "addFmva", vus: 1, iterations: 1 }, + "testcase-9-kaste-styret": { executor: "shared-iterations", exec: "kasteStyret", vus: 1, iterations: 1 }, + }, +}; + +export { nameShortChange, addFmva, fadrChange, daglChange, contactChange, styrChange, addMedl, removeMedl, kasteStyret }; + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; diff --git a/K6/api/tests/register/er-sync/testcase_10_delete_org.js b/K6/api/tests/register/er-sync/testcase_10_delete_org.js new file mode 100644 index 00000000..0761c828 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_10_delete_org.js @@ -0,0 +1,101 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_10_delete_org.js + * @description Verifies that deleting an organization (hovedsakstype="S") in ER + * is correctly synced to Altinn Register and revokes access for existing role holders. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-10-delete-org": { executor: "shared-iterations", exec: "deleteOrg", vus: 1, iterations: 1 }, + }, +}; + +const DAGLIG_LEDER = { fnr: "22876298973", fornavn: "OFFISIELL", slektsnavn: "ÆRESDOKTOR" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + SLETT ORG TEST AS + SLETT ORG TEST AS + + + 0150 + NO + 0301 + Testveien 1 + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 10 + NO + L + + + + `); +} + +export function deleteOrg() { + const orgNr = generateOrgNr(); + console.log(`[TC10] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - register org with DAGL and wait for Register + runErSyncTestcase( + "10. Slett org - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm DAGL has access before testing deletion + group("Verify - DAGL has access to org after prep", () => { + const parties = retryUntilHasAccess(apClient, DAGLIG_LEDER.fnr, orgNr, "10. Slett org - DAGL access granted"); + console.log(`[TC10] Authorized parties for ${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn} after prep: ${JSON.stringify(parties)}`); + }); + + // Phase 3: Submit org deletion + group("Change - submit org deletion", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Verify DAGL no longer has access after org deletion + group("Verify - DAGL no longer has access after org deletion", () => { + const parties = retryUntilNoAccess(apClient, DAGLIG_LEDER.fnr, orgNr, "10. Slett org - DAGL access revoked"); + console.log(`[TC10] Authorized parties for ${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn} after deletion: ${JSON.stringify(parties)}`); + check(parties, { + [`${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn} no longer has access to deleted org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; diff --git a/K6/api/tests/register/er-sync/testcase_11_kont_nuf.js b/K6/api/tests/register/er-sync/testcase_11_kont_nuf.js new file mode 100644 index 00000000..feb95c05 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_11_kont_nuf.js @@ -0,0 +1,142 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_11_kont_nuf.js + * @description Verifies that adding a KONT (kontaktperson) role to a NUF organization + * also grants kontaktperson-nuf access (secondary role dispatch), and that removing + * KONT revokes access for both roles. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-11-kont-nuf": { executor: "shared-iterations", exec: "kontNuf", vus: 1, iterations: 1 }, + }, +}; + +const DAGLIG_LEDER = { fnr: "27877699310", fornavn: "INKONSEKVENT", slektsnavn: "POTET" }; +const KONTAKTPERSON = { fnr: "30915999766", fornavn: "OPPRETT", slektsnavn: "FASTE" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + KONT NUF TEST NUF + KONT NUF TEST NUF + + + 0150 + NO + 0301 + Testveien 1 + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 10 + NO + L + + + N + 1 + ${KONTAKTPERSON.fnr} + ${KONTAKTPERSON.fornavn} + ${KONTAKTPERSON.slektsnavn} + 0150 + Testveien 11 + NO + L + + + + `); +} + +export function kontNuf() { + const orgNr = generateOrgNr(); + console.log(`[TC11] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn}) | KONTAKTPERSON: ${KONTAKTPERSON.fnr} (${KONTAKTPERSON.fornavn} ${KONTAKTPERSON.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + ${KONTAKTPERSON.fnr} + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - register NUF org with DAGL + KONT and wait for Register + runErSyncTestcase( + "11. KONT på NUF - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm KONT has access before testing removal + // KONT on a NUF org should grant both kontaktperson and kontaktperson-nuf + group("Verify - KONT has access to org after prep", () => { + retryUntilHasAccess(apClient, KONTAKTPERSON.fnr, orgNr, "11. KONT på NUF - KONT access granted"); + }); + + // Phase 3: Submit KONT removal + group("Change - remove KONT", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Verify KONT no longer has access (both kontaktperson and kontaktperson-nuf revoked) + group("Verify - KONT no longer has access after removal", () => { + const parties = retryUntilNoAccess(apClient, KONTAKTPERSON.fnr, orgNr, "11. KONT på NUF - KONT access revoked"); + check(parties, { + [`${KONTAKTPERSON.fornavn} ${KONTAKTPERSON.slektsnavn} no longer has access to org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + // Phase 5: Verify DAGL still has access (KONT removal should not affect DAGL) + group("Verify - DAGL retains access after KONT removal", () => { + const parties = retryUntilHasAccess(apClient, DAGLIG_LEDER.fnr, orgNr, "11. KONT på NUF - DAGL unaffected"); + check(parties, { + [`${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn} (DAGL) still has access after KONT removal`]: (p) => + Array.isArray(p) && p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_1_change_org_name.js b/K6/api/tests/register/er-sync/testcase_1_change_org_name.js new file mode 100644 index 00000000..437e8a64 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_1_change_org_name.js @@ -0,0 +1,97 @@ +import { group } from "k6"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope } from "./helper.js"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; + +/** + * @file testcase_1_change_org_name.js + * @description Verifies that a change to NAVN (short name) in ER is correctly + * synced to Altinn Register. + * + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-1-change-org-name": { executor: "shared-iterations", exec: "nameShortChange", vus: 1, iterations: 1 }, + }, +}; + +const INNEHAVER = { fnr: "31927398861", fornavn: "RØD", slektsnavn: "TRANE" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + 😍😍😍 Den beste orgen 😍😍😍 + 😍 rednavn 😍 + + + 1234 + NO + 0301 + Testveien 1 + + + N + 1 + ${INNEHAVER.fnr} + ${INNEHAVER.fornavn} + ${INNEHAVER.slektsnavn} + 1234 + Testveien 29 + NO + L + + + + `); +} + +export function nameShortChange() { + const orgNr = generateOrgNr(); + console.log(`[TC1] orgNr: ${orgNr} | INNEHAVER: ${INNEHAVER.fnr} (${INNEHAVER.fornavn} ${INNEHAVER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + NAVN CHANGE TEST ENK OPPDATERT + NAVN CHANGE TEST ENK OPPDATERT + + + + `); + + runErSyncTestcase( + "1. Change org name", + prep, + change, + orgNr, + { "org name updated to NAVN CHANGE TEST ENK OPPDATERT": (p) => p.displayName === "NAVN CHANGE TEST ENK OPPDATERT" }, + ); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${INNEHAVER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_2_add_styremedlem.js b/K6/api/tests/register/er-sync/testcase_2_add_styremedlem.js new file mode 100644 index 00000000..62f1ce13 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_2_add_styremedlem.js @@ -0,0 +1,123 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess } from "./helper.js"; + +/** + * @file testcase_2_add_styremedlem.js + * @description Verifies that adding a MEDL (Styremedlem) in ER is correctly + * synced to Altinn Register and reflected in authorized parties. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-2-add-styremedlem": { executor: "shared-iterations", exec: "addMedl", vus: 1, iterations: 1 }, + }, +}; + +const DAGLIG_LEDER = { fnr: "09861798434", fornavn: "AKADEMISK", slektsnavn: "HAKE" }; +const NYTT_STYREMEDLEM = { fnr: "10921148513", fornavn: "UKLAR", slektsnavn: "PLAST" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + ADD MEDL TEST AS + ADD MEDL TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function addMedl() { + const orgNr = generateOrgNr(); + console.log(`[TC2] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn}) | NYTT_STYREMEDLEM: ${NYTT_STYREMEDLEM.fnr} (${NYTT_STYREMEDLEM.fornavn} ${NYTT_STYREMEDLEM.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + N + 1 + ${NYTT_STYREMEDLEM.fnr} + ${NYTT_STYREMEDLEM.fornavn} + ${NYTT_STYREMEDLEM.slektsnavn} + 0150 + Testveien 12 + NO + L + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + runErSyncTestcase( + "2. Add styremedlem (MEDL)", + prep, + change, + orgNr, + { "org is accessible in Register after MEDL added": (p) => p.organizationIdentifier === orgNr }, + ); + + group("Verify - new MEDL has access to org", () => { + const parties = retryUntilHasAccess(apClient, NYTT_STYREMEDLEM.fnr, orgNr, "add-board-member - new MEDL access"); + check(parties, { + [`new MEDL (${NYTT_STYREMEDLEM.fornavn} ${NYTT_STYREMEDLEM.slektsnavn}) has access to org`]: (p) => + Array.isArray(p) && p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${DAGLIG_LEDER.fnr} + + + ${NYTT_STYREMEDLEM.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_3_remove_styremedlem.js b/K6/api/tests/register/er-sync/testcase_3_remove_styremedlem.js new file mode 100644 index 00000000..f5fd0f55 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_3_remove_styremedlem.js @@ -0,0 +1,137 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_3_remove_styremedlem.js + * @description Verifies that removing a MEDL (Styremedlem) in ER is correctly + * synced to Altinn Register and reflected in authorized parties. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-3-remove-styremedlem": { executor: "shared-iterations", exec: "removeMedl", vus: 1, iterations: 1 }, + }, +}; + +const DAGLIG_LEDER = { fnr: "26827896992", fornavn: "VIKTIG", slektsnavn: "ORIDÉ" }; +const STYREMEDLEM = { fnr: "10921148513", fornavn: "UKLAR", slektsnavn: "PLAST" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + REMOVE MEDL TEST AS + REMOVE MEDL TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${STYREMEDLEM.fnr} + ${STYREMEDLEM.fornavn} + ${STYREMEDLEM.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function removeMedl() { + const orgNr = generateOrgNr(); + console.log(`[TC3] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn}) | STYREMEDLEM: ${STYREMEDLEM.fnr} (${STYREMEDLEM.fornavn} ${STYREMEDLEM.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + ${STYREMEDLEM.fnr} + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - submit org with MEDL+DAGL and wait for Register + runErSyncTestcase( + "3. Remove styremedlem (MEDL) - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm MEDL actually has access before testing removal + group("Verify - MEDL has access to org after prep", () => { + retryUntilHasAccess(apClient, STYREMEDLEM.fnr, orgNr, "3. Remove styremedlem - MEDL access granted"); + }); + + // Phase 3: Submit the MEDL removal + group("Change - submit MEDL removal", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Poll until MEDL no longer appears in authorized parties + group("Verify - MEDL no longer has access to org", () => { + const parties = retryUntilNoAccess(apClient, STYREMEDLEM.fnr, orgNr, "3. Remove styremedlem - MEDL access revoked"); + check(parties, { + [`MEDL (${STYREMEDLEM.fornavn} ${STYREMEDLEM.slektsnavn}) no longer has access to org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_4_replace_daglig_leder.js b/K6/api/tests/register/er-sync/testcase_4_replace_daglig_leder.js new file mode 100644 index 00000000..05227e0d --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_4_replace_daglig_leder.js @@ -0,0 +1,171 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_4_replace_daglig_leder.js + * @description Verifies that a change to DAGL (Daglig leder) in ER is correctly + * synced to Altinn Register and reflected in authorized parties. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-4-replace-daglig-leder": { executor: "shared-iterations", exec: "daglChange", vus: 1, iterations: 1 }, + }, +}; + +const OLD_DAGLIG_LEDER = { fnr: "20875798538", fornavn: "TALEFØR", slektsnavn: "HAKE" }; +const NEW_DAGLIG_LEDER = { fnr: "26858396815", fornavn: "FLYKTIG", slektsnavn: "GASSPEDAL" }; +const STYRELEDER = { fnr: "02895823468", fornavn: "Anne", slektsnavn: "Testperson" }; +const STYREMEDLEM = { fnr: "07855812899", fornavn: "Ola Test", slektsnavn: "Testperson" }; + + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + DAGL CHANGE TEST AS + DAGL CHANGE TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${STYRELEDER.fnr} + ${STYRELEDER.fornavn} + ${STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + N + 1 + ${STYREMEDLEM.fnr} + ${STYREMEDLEM.fornavn} + ${STYREMEDLEM.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 1 + ${OLD_DAGLIG_LEDER.fnr} + ${OLD_DAGLIG_LEDER.fornavn} + ${OLD_DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function daglChange() { + const orgNr = generateOrgNr(); + console.log(`[TC4] orgNr: ${orgNr} | OLD_DAGL: ${OLD_DAGLIG_LEDER.fnr} (${OLD_DAGLIG_LEDER.fornavn} ${OLD_DAGLIG_LEDER.slektsnavn}) | NEW_DAGL: ${NEW_DAGLIG_LEDER.fnr} (${NEW_DAGLIG_LEDER.fornavn} ${NEW_DAGLIG_LEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + ${OLD_DAGLIG_LEDER.fnr} + + + ${NEW_DAGLIG_LEDER.fnr} + ${NEW_DAGLIG_LEDER.fornavn} + ${NEW_DAGLIG_LEDER.slektsnavn} + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - submit org with OLD_DAGL and wait for Register + runErSyncTestcase( + "4. Replace daglig leder (DAGL) - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm OLD_DAGL has access before testing replacement + group("Verify - old DAGL has access to org after prep", () => { + retryUntilHasAccess(apClient, OLD_DAGLIG_LEDER.fnr, orgNr, "4. Replace daglig leder - old DAGL access granted"); + }); + + // Phase 3: Submit the DAGL replacement + group("Change - submit DAGL replacement", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Verify new DAGL has access + group("Verify - new DAGL has access to org", () => { + const parties = retryUntilHasAccess(apClient, NEW_DAGLIG_LEDER.fnr, orgNr, "replace-daglig-leder - new DAGL access"); + check(parties, { + [`new DAGL (${NEW_DAGLIG_LEDER.fornavn} ${NEW_DAGLIG_LEDER.slektsnavn}) has access to org`]: (p) => + Array.isArray(p) && p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + // Phase 5: Verify old DAGL no longer has access + group("Verify - old DAGL no longer has access to org", () => { + const parties = retryUntilNoAccess(apClient, OLD_DAGLIG_LEDER.fnr, orgNr, "replace-daglig-leder - old DAGL access revoked"); + check(parties, { + [`old DAGL (${OLD_DAGLIG_LEDER.fornavn} ${OLD_DAGLIG_LEDER.slektsnavn}) no longer has access to org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${STYRELEDER.fnr} + + + ${STYREMEDLEM.fnr} + + + ${NEW_DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_5_replace_styreleder.js b/K6/api/tests/register/er-sync/testcase_5_replace_styreleder.js new file mode 100644 index 00000000..0683b0b1 --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_5_replace_styreleder.js @@ -0,0 +1,172 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_5_replace_styreleder.js + * @description Verifies that a change to LEDE (Styreleder) in ER is correctly + * synced to Altinn Register and reflected in authorized parties. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-5-replace-styreleder": { executor: "shared-iterations", exec: "styrChange", vus: 1, iterations: 1 }, + }, +}; + +const OLD_STYRELEDER = { fnr: "16918598441", fornavn: "TREG", slektsnavn: "HUNKATT" }; +const NEW_STYRELEDER = { fnr: "20845996750", fornavn: "TYPISK", slektsnavn: "TIMEBU" }; +const STYREMEDLEM = { fnr: "57925901581", fornavn: "PASSIV", slektsnavn: "EKORNHALE" }; +const DAGLIG_LEDER = { fnr: "18914598245", fornavn: "UTÅLMODIG", slektsnavn: "MASKIN" }; + + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + BYTTE STYRELEDER AS + BYTTE STYRELEDER AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${OLD_STYRELEDER.fnr} + ${OLD_STYRELEDER.fornavn} + ${OLD_STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + N + 1 + ${STYREMEDLEM.fnr} + ${STYREMEDLEM.fornavn} + ${STYREMEDLEM.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function styrChange() { + const orgNr = generateOrgNr(); + console.log(`[TC5] orgNr: ${orgNr} | OLD_STYR: ${OLD_STYRELEDER.fnr} (${OLD_STYRELEDER.fornavn} ${OLD_STYRELEDER.slektsnavn}) | NEW_STYR: ${NEW_STYRELEDER.fnr} (${NEW_STYRELEDER.fornavn} ${NEW_STYRELEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + ${OLD_STYRELEDER.fnr} + + + ${NEW_STYRELEDER.fnr} + ${NEW_STYRELEDER.fornavn} + ${NEW_STYRELEDER.slektsnavn} + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - submit org with OLD_STYR and wait for Register + runErSyncTestcase( + "5. Replace styreleder (STYR) - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm OLD_STYR has access before testing replacement + group("Verify - old STYR has access to org after prep", () => { + retryUntilHasAccess(apClient, OLD_STYRELEDER.fnr, orgNr, "5. Replace styreleder - old STYR access granted"); + }); + + // Phase 3: Submit the STYR replacement + group("Change - submit STYR replacement", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Verify new STYR has access + group("Verify - new STYR has access to org", () => { + const parties = retryUntilHasAccess(apClient, NEW_STYRELEDER.fnr, orgNr, "replace-styreleder - new STYR access"); + check(parties, { + [`new Styreleder (${NEW_STYRELEDER.fornavn} ${NEW_STYRELEDER.slektsnavn}) has access to org`]: (p) => + Array.isArray(p) && p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + // Phase 5: Verify old STYR no longer has access + group("Verify - old STYR no longer has access to org", () => { + const parties = retryUntilNoAccess(apClient, OLD_STYRELEDER.fnr, orgNr, "replace-styreleder - old STYR access revoked"); + check(parties, { + [`old STYR (${OLD_STYRELEDER.fornavn} ${OLD_STYRELEDER.slektsnavn}) no longer has access to org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${NEW_STYRELEDER.fnr} + + + ${STYREMEDLEM.fnr} + + + ${DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_6_change_forretningsadresse.js b/K6/api/tests/register/er-sync/testcase_6_change_forretningsadresse.js new file mode 100644 index 00000000..dcf47adf --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_6_change_forretningsadresse.js @@ -0,0 +1,152 @@ +import { group } from "k6"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope } from "./helper.js"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; + +/** + * @file testcase_6_change_forretningsadresse.js + * @description Verifies that a change to FADR (Forretningsadresse) in ER is correctly + * synced to Altinn Register. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-6-change-forretningsadresse": { executor: "shared-iterations", exec: "fadrChange", vus: 1, iterations: 1 }, + }, +}; + +const STYRELEDER = { fnr: "02831899053", fornavn: "LILLA", slektsnavn: "NETTADRESSE" }; +const STYREMEDLEM = { fnr: "03823648714", fornavn: "SEIN", slektsnavn: "ELV" }; +const STYREMEDLEM2 = { fnr: "26812099719", fornavn: "STOR", slektsnavn: "KAPPE" }; +const DAGLIG_LEDER = { fnr: "05830299450", fornavn: "SPENNENDE", slektsnavn: "BRØKSTREK" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + FADR CHANGE TEST AS + FADR CHANGE TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${STYRELEDER.fnr} + ${STYRELEDER.fornavn} + ${STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + N + 1 + ${STYREMEDLEM.fnr} + ${STYREMEDLEM.fornavn} + ${STYREMEDLEM.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 2 + ${STYREMEDLEM2.fnr} + ${STYREMEDLEM2.fornavn} + ${STYREMEDLEM2.slektsnavn} + 0150 + Testveien 13 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function fadrChange() { + const orgNr = generateOrgNr(); + console.log(`[TC6] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + 0350 + NO + 0301 + Ny Forretningsgate 5 + + + + `); + + runErSyncTestcase( + "6. Change forretningsadresse (FADR)", + prep, + change, + orgNr, + { + "org businessAddress updated to Ny Forretningsgate 5": (p) => p.businessAddress?.address?.startsWith("Ny Forretningsgate 5"), + "org businessAddress postalCode updated to 0350": (p) => p.businessAddress?.postalCode === "0350", + }, + ); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${STYRELEDER.fnr} + + + ${STYREMEDLEM.fnr} + + + ${STYREMEDLEM2.fnr} + + + ${DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_7_update_contact_info.js b/K6/api/tests/register/er-sync/testcase_7_update_contact_info.js new file mode 100644 index 00000000..0c87f59d --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_7_update_contact_info.js @@ -0,0 +1,142 @@ +import { group } from "k6"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope } from "./helper.js"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; + +/** + * @file testcase_7_update_contact_info.js + * @description Verifies that changes to contact information (TFON, TFAX, EPOS, IADR) in ER + * are correctly synced to Altinn Register. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-7-update-contact-info": { executor: "shared-iterations", exec: "contactChange", vus: 1, iterations: 1 }, + }, +}; + +const STYRELEDER = { fnr: "28824198537", fornavn: "SNÅL", slektsnavn: "LERKE" }; +const DAGLIG_LEDER = { fnr: "57896202792", fornavn: "INTERESSERT", slektsnavn: "FANGE" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + CONTACT CHANGE TEST AS + CONTACT CHANGE TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + 22334455 + + + 22334456 + + + contact-test@example.com + + + http://initial.example.com + + + N + 1 + ${STYRELEDER.fnr} + ${STYRELEDER.fornavn} + ${STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 14 + NO + L + + + + `); +} + +export function contactChange() { + const orgNr = generateOrgNr(); + console.log(`[TC7] orgNr: ${orgNr} | DAGLIG_LEDER: ${DAGLIG_LEDER.fnr} (${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + 99887711 + + + 99887712 + + + contact-test-oppdatert@example.com + + + http://oppdatert.example.com + + + + `); + + runErSyncTestcase( + "7. Update contact info", + prep, + change, + orgNr, + { + "org telephoneNumber updated to 99887711": (p) => p.telephoneNumber === "99887711", + "org faxNumber updated to 99887712": (p) => p.faxNumber === "99887712", + "org emailAddress updated to contact-test-oppdatert@example.com": (p) => p.emailAddress === "contact-test-oppdatert@example.com", + "org internetAddress updated to http://oppdatert.example.com": (p) => p.internetAddress === "http://oppdatert.example.com", + }, + ); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${STYRELEDER.fnr} + + + ${DAGLIG_LEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_8_add_frivillig_mva.js b/K6/api/tests/register/er-sync/testcase_8_add_frivillig_mva.js new file mode 100644 index 00000000..af1c61ee --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_8_add_frivillig_mva.js @@ -0,0 +1,95 @@ +import { group } from "k6"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope } from "./helper.js"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; + +/** + * @file testcase_8_add_frivillig_mva.js + * @description Verifies that adding FMVA (Frivillig MVA-registrering) in ER is correctly + * synced to Altinn Register. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-8-add-frivillig-mva": { executor: "shared-iterations", exec: "addFmva", vus: 1, iterations: 1 }, + }, +}; + +const STYRELEDER = { fnr: "02895823468", fornavn: "Anne", slektsnavn: "Testperson" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + FMVA ADD TEST AS + FMVA ADD TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${STYRELEDER.fnr} + ${STYRELEDER.fornavn} + ${STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + + `); +} + +export function addFmva() { + const orgNr = generateOrgNr(); + console.log(`[TC8] orgNr: ${orgNr} | STYRELEDER: ${STYRELEDER.fnr} (${STYRELEDER.fornavn} ${STYRELEDER.slektsnavn})`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + OFVA + + + + `); + + runErSyncTestcase( + "8. Add frivillig MVA (FMVA)", + prep, + change, + orgNr, + { "org is accessible in Register after FMVA added": (p) => p.organizationIdentifier === orgNr }, + ); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${STYRELEDER.fnr} + + + + `); +} diff --git a/K6/api/tests/register/er-sync/testcase_9_kaste_styret.js b/K6/api/tests/register/er-sync/testcase_9_kaste_styret.js new file mode 100644 index 00000000..86fb729b --- /dev/null +++ b/K6/api/tests/register/er-sync/testcase_9_kaste_styret.js @@ -0,0 +1,239 @@ +import { group, check } from "k6"; +import { RegisterApiClient } from "../../../../clients/authentication/index.js"; +import { SubmitErData } from "../../../building-blocks/register/index.js"; +import { generateOrgNr } from "../../../../helpers.js"; +import { runErSyncTestcase, buildErSoapEnvelope, createAuthorizedPartiesClient, retryUntilHasAccess, retryUntilNoAccess } from "./helper.js"; + +/** + * @file testcase_9_kaste_styret.js + * @description Verifies that dismissing the entire board (samendringUtgaar SAMU/STYR) in ER + * is correctly synced to Altinn Register. + * @see README.md + */ + +export const options = { + scenarios: { + "testcase-9-kaste-styret": { executor: "shared-iterations", exec: "kasteStyret", vus: 1, iterations: 1 }, + }, +}; + +const STYRELEDER = { fnr: "11814997261", fornavn: "VRIEN", slektsnavn: "EKSPLOSJON" }; +const NESTLEDER = { fnr: "08924998319", fornavn: "ØVRIGE", slektsnavn: "EGGEPLOMME" }; +const DAGLIG_LEDER = { fnr: "28917699196", fornavn: "LANGFINGRET", slektsnavn: "BÅNDSALAT" }; + +const STYREMEDLEM2 = { fnr: "18914598245", fornavn: "UTÅLMODIG", slektsnavn: "MASKIN" }; +const STYREMEDLEM3 = { fnr: "05830299450", fornavn: "SPENNENDE", slektsnavn: "BRØKSTREK" }; +const STYREMEDLEM4 = { fnr: "26827896992", fornavn: "VIKTIG", slektsnavn: "ORIDÉ" }; +const OBSERVATØR = { fnr: "28824198537", fornavn: "SNÅL", slektsnavn: "LERKE" }; + +function buildPrepXml(orgNr) { + return buildErSoapEnvelope(` + + + + KASTE STYRET TEST AS + KASTE STYRET TEST AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + ${STYRELEDER.fnr} + ${STYRELEDER.fornavn} + ${STYRELEDER.slektsnavn} + 0150 + Testveien 11 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 1 + ${DAGLIG_LEDER.fnr} + ${DAGLIG_LEDER.fornavn} + ${DAGLIG_LEDER.slektsnavn} + 0150 + Testveien 12 + NO + L + + + N + 2 + ${STYREMEDLEM2.fnr} + ${STYREMEDLEM2.fornavn} + ${STYREMEDLEM2.slektsnavn} + 0150 + Testveien 13 + NO + L + + + N + 3 + ${STYREMEDLEM3.fnr} + ${STYREMEDLEM3.fornavn} + ${STYREMEDLEM3.slektsnavn} + 0150 + Testveien 14 + NO + L + + + N + 4 + ${STYREMEDLEM4.fnr} + ${STYREMEDLEM4.fornavn} + ${STYREMEDLEM4.slektsnavn} + 0150 + Testveien 15 + NO + L + + + N + 1 + ${NESTLEDER.fnr} + ${NESTLEDER.fornavn} + ${NESTLEDER.slektsnavn} + 0150 + Testveien 16 + NO + L + + + N + 1 + ${OBSERVATØR.fnr} + ${OBSERVATØR.fornavn} + ${OBSERVATØR.slektsnavn} + 0150 + Testveien 17 + NO + L + + + + `); +} + +export function kasteStyret() { + const orgNr = generateOrgNr(); + console.log(`[TC9] orgNr: ${orgNr} | STYRELEDER: ${STYRELEDER.fnr} | NESTLEDER: ${NESTLEDER.fnr} | STYREMEDLEM1 (also DAGL): ${DAGLIG_LEDER.fnr} | STYREMEDLEM2: ${STYREMEDLEM2.fnr} | STYREMEDLEM3: ${STYREMEDLEM3.fnr} | STYREMEDLEM4: ${STYREMEDLEM4.fnr} | OBSERVATØR: ${OBSERVATØR.fnr}`); + + const prep = buildPrepXml(orgNr); + + const change = buildErSoapEnvelope(` + + + + STYR + + + + `); + + const apClient = createAuthorizedPartiesClient(); + + // Phase 1: Prep - submit org with full board and wait for Register + runErSyncTestcase( + "9. Kaste styret (SAMU/STYR) - Prep", + prep, + change, + orgNr, + {}, + { stopAfterPrep: true }, + ); + + // Phase 2: Confirm all board members have access before testing dismissal + group("Verify - all board members have access after prep", () => { + const allMembers = [STYRELEDER, NESTLEDER, DAGLIG_LEDER, STYREMEDLEM2, STYREMEDLEM3, STYREMEDLEM4, OBSERVATØR]; + for (const person of allMembers) { + retryUntilHasAccess(apClient, person.fnr, orgNr, `9. Kaste styret - ${person.fornavn} ${person.slektsnavn} access granted`); + } + }); + + // Phase 3: Submit board dismissal + group("Change - submit board dismissal", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, change, "Change"); + }); + + // Phase 4: Verify board-only members no longer have access + group("Verify - board members no longer have access after dismissal", () => { + const boardOnlyMembers = [STYRELEDER, NESTLEDER, STYREMEDLEM2, STYREMEDLEM3, STYREMEDLEM4, OBSERVATØR]; + for (const person of boardOnlyMembers) { + const parties = retryUntilNoAccess(apClient, person.fnr, orgNr, `9. Kaste styret - ${person.fornavn} ${person.slektsnavn} access revoked`); + check(parties, { + [`${person.fornavn} ${person.slektsnavn} no longer has access to org`]: (p) => + Array.isArray(p) && !p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + } + }); + + // Phase 5: Verify DAGLIG LEDER still has access via DAGL (SAMU/STYR does not remove DAGL) + group("Verify - DAGL retains access via DAGL after board dismissal", () => { + const parties = retryUntilHasAccess(apClient, DAGLIG_LEDER.fnr, orgNr, "9. Kaste styret - DAGL retains DAGL access"); + check(parties, { + [`${DAGLIG_LEDER.fornavn} ${DAGLIG_LEDER.slektsnavn} (DAGL) still has access to org after board dismissal`]: (p) => + Array.isArray(p) && p.some((party) => party.organizationNumber === orgNr || party.orgNumber === orgNr), + }); + }); + + group("Cleanup", () => { + const apiClient = new RegisterApiClient(__ENV.BASE_URL, null); + SubmitErData(apiClient, buildCleanupXml(orgNr), "Cleanup"); + }); +} + +// Reporting tools +export { handleSummary } from "./er-sync-summary.js"; + +function buildCleanupXml(orgNr) { + return buildErSoapEnvelope(` + + + + ${STYRELEDER.fnr} + + + ${DAGLIG_LEDER.fnr} + + + ${DAGLIG_LEDER.fnr} + + + ${STYREMEDLEM2.fnr} + + + ${STYREMEDLEM3.fnr} + + + ${STYREMEDLEM4.fnr} + + + ${NESTLEDER.fnr} + + + ${OBSERVATØR.fnr} + + + + `); +} diff --git a/K6/clients/authentication/register.js b/K6/clients/authentication/register.js index efec1594..16685bb8 100644 --- a/K6/clients/authentication/register.js +++ b/K6/clients/authentication/register.js @@ -4,6 +4,7 @@ const TAGS = { RemoveRevisorRoleFromEr: { action: "RemoveRevisorRoleFromEr" }, AddRevisorRoleToErForOrg: { action: "AddRevisorRoleToErForOrg" }, GetRevisorCustomerIdentifiersForParty: { action: "GetRevisorCustomerIdentifiersForParty" }, + SubmitErData: { action: "SubmitErData" }, }; class RegisterApiClient { @@ -112,6 +113,28 @@ class RegisterApiClient { ); } + /** + * Posts a pre-built SOAP envelope to the ER update endpoint. + * The caller is responsible for loading the XML file and substituting + * ${soapErUsername} and ${soapErPassword} before passing the body here. + * + * @param {string} soapBody - Complete SubmitERDataBasic SOAP envelope + * @returns http.RefinedResponse + */ + SubmitErData(soapBody) { + const registerUrl = `${__ENV.BASE_URL}/enhets-registeret/api/v1/update.svc?record=false`; + const submitERDataBasic = "\"http://www.altinn.no/services/Register/ER/2013/06/IRegisterERExternalBasic/SubmitERDataBasic\""; + + return http.post(registerUrl, soapBody, { + tags: { name: registerUrl, endpoint: registerUrl }, + headers: { + "Content-Type": "text/xml", + SOAPAction: submitERDataBasic, + "X-Altinn-Register-Ccr": "Apply-In-A3", + }, + }); + } + GetRevisorCustomerIdentifiersForParty(facilitatorPartyUuid, subscriptionKey) { const token = this.tokenGenerator.getToken(); const url = `${this.FULL_PATH}/internal/parties/${facilitatorPartyUuid}/customers/ccr/revisor`; diff --git a/K6/functional-tests-summary.js b/K6/functional-tests-summary.js index fa81a48e..1c6b952f 100644 --- a/K6/functional-tests-summary.js +++ b/K6/functional-tests-summary.js @@ -49,7 +49,7 @@ export function handleSummary(data) { } return { - // If you dont append on the initial lines when using stdout, it wont print the last check?? - stdout: lines.join("\n") + "\n\n=== END SUMMARY === \n\n", + // If you dont append on the initial lines when using stdout, it wont print the last check?? + stdout: lines.join("\n") + "\n\n \n\n", }; } diff --git a/K6/helpers.js b/K6/helpers.js index 7ab383b0..45fe842f 100644 --- a/K6/helpers.js +++ b/K6/helpers.js @@ -28,16 +28,11 @@ export function retry(conditionFn, options = {}) { const result = conditionFn(); if (result) { - console.log(`${testscenario}] condition met on attempt ${attempt}`); success = true; break; } - - console.log( - `${testscenario}] Attempt ${attempt}/${retries} — condition not met, retrying...` - ); } catch (err) { - console.warn(`${testscenario}: Error on attempt ${attempt}:`); + console.warn(`[${testscenario}] Error on attempt ${attempt}: ${err}`); } if (attempt < retries) { @@ -132,6 +127,36 @@ export function getOptions(labels, groups = []) { return options; } +/** + * Generates a random syntetically valid Norwegian organization number. + * The checksum algorithm follows Enhetsregisteret's Modulus 11 specification. + * First digit is restricted to 2–6 to avoid ranges used by real enterprises. + * + * @returns {string} A 9-digit organization number string + */ +export function generateOrgNr() { + const weights = [3, 2, 7, 6, 5, 4, 3, 2]; + + while (true) { + const digits = new Array(9); + digits[0] = Math.floor(Math.random() * 5) + 2; // 2–6 + for (let i = 1; i < 8; i++) { + digits[i] = Math.floor(Math.random() * 10); + } + + let sum = 0; + for (let i = 0; i < 8; i++) { + sum += digits[i] * weights[i]; + } + + const checkDigit = 11 - (sum % 11); + if (checkDigit === 10) continue; // invalid combination, retry + digits[8] = checkDigit === 11 ? 0 : checkDigit; + + return digits.join(""); + } +} + export function checkIp(ip) { const ipv4 = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; diff --git a/K6/testdata/register/ER-data/testcase-add-board-member/add-board-member.xml b/K6/testdata/register/ER-data/testcase-add-board-member/add-board-member.xml new file mode 100644 index 00000000..9632422e --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-board-member/add-board-member.xml @@ -0,0 +1,49 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-add-board-member/prep.xml b/K6/testdata/register/ER-data/testcase-add-board-member/prep.xml new file mode 100644 index 00000000..c177b2d7 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-board-member/prep.xml @@ -0,0 +1,48 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC BRL + ER SYNC BRL + + + 0150 + NO + 0301 + Testveien 40 + + + N + 1 + 56928201177 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-add-fmva/add-fmva.xml b/K6/testdata/register/ER-data/testcase-add-fmva/add-fmva.xml new file mode 100644 index 00000000..ab884142 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-fmva/add-fmva.xml @@ -0,0 +1,19 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + OFVA + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-add-fmva/prep.xml b/K6/testdata/register/ER-data/testcase-add-fmva/prep.xml new file mode 100644 index 00000000..559cc443 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-fmva/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 20856896839 + Idiotsikker + Harmoni + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-add-paat/add-paat.xml b/K6/testdata/register/ER-data/testcase-add-paat/add-paat.xml new file mode 100644 index 00000000..272bc5e5 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-paat/add-paat.xml @@ -0,0 +1,19 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + J + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-add-paat/prep.xml b/K6/testdata/register/ER-data/testcase-add-paat/prep.xml new file mode 100644 index 00000000..b4c34a71 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-add-paat/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC PAAT AS + ER SYNC PAAT AS + + + 0150 + NO + 0301 + Testveien 60 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-board-chair-change/change-board-chair.xml b/K6/testdata/register/ER-data/testcase-board-chair-change/change-board-chair.xml new file mode 100644 index 00000000..f378fda2 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-board-chair-change/change-board-chair.xml @@ -0,0 +1,60 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + J + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 28816327530 + Frida Test + Testperson + 0150 + Testveien 20 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-board-chair-change/prep.xml b/K6/testdata/register/ER-data/testcase-board-chair-change/prep.xml new file mode 100644 index 00000000..a7c08731 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-board-chair-change/prep.xml @@ -0,0 +1,59 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-contact-change/change-contact.xml b/K6/testdata/register/ER-data/testcase-contact-change/change-contact.xml new file mode 100644 index 00000000..4336ccd9 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-contact-change/change-contact.xml @@ -0,0 +1,23 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 99887766 + + + er-sync-enk-oppdatert@example.com + + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-contact-change/prep.xml b/K6/testdata/register/ER-data/testcase-contact-change/prep.xml new file mode 100644 index 00000000..edbe558c --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-contact-change/prep.xml @@ -0,0 +1,46 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC ENK + ER SYNC ENK + + + 1234 + NO + 0301 + Testveien 1 + + + er-sync-enk@example.com + + + 22334455 + + + +4799999999 + + + N + 1 + 12864421537 + Elise + Testperson + 1234 + Testveien 29 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-dagl-change/change-dagl.xml b/K6/testdata/register/ER-data/testcase-dagl-change/change-dagl.xml new file mode 100644 index 00000000..d0957fef --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-dagl-change/change-dagl.xml @@ -0,0 +1,38 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + J + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + N + 1 + 28816327530 + Frida Test + Testperson + 0150 + Testveien 20 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-dagl-change/prep.xml b/K6/testdata/register/ER-data/testcase-dagl-change/prep.xml new file mode 100644 index 00000000..0b64ec03 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-dagl-change/prep.xml @@ -0,0 +1,65 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-fadr-change/change-fadr.xml b/K6/testdata/register/ER-data/testcase-fadr-change/change-fadr.xml new file mode 100644 index 00000000..244bfa7c --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-fadr-change/change-fadr.xml @@ -0,0 +1,22 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 0350 + NO + 0301 + Ny Forretningsgate 5 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-fadr-change/prep.xml b/K6/testdata/register/ER-data/testcase-fadr-change/prep.xml new file mode 100644 index 00000000..9ccad71c --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-fadr-change/prep.xml @@ -0,0 +1,76 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + N + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-multi-infotype/multi-infotype-change.xml b/K6/testdata/register/ER-data/testcase-multi-infotype/multi-infotype-change.xml new file mode 100644 index 00000000..b3efadef --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-multi-infotype/multi-infotype-change.xml @@ -0,0 +1,34 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 0350 + NO + 0301 + Ny Forretningsgate 5 + + + 0160 + NO + 0301 + Postboks 456 + + + 99887711 + + + er-sync-as-oppdatert@example.com + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-multi-infotype/prep.xml b/K6/testdata/register/ER-data/testcase-multi-infotype/prep.xml new file mode 100644 index 00000000..43502fb3 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-multi-infotype/prep.xml @@ -0,0 +1,60 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + 22334455 + + + er-sync-as@example.com + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-name-long-change/change-name-long.xml b/K6/testdata/register/ER-data/testcase-name-long-change/change-name-long.xml new file mode 100644 index 00000000..d6aceff8 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-name-long-change/change-name-long.xml @@ -0,0 +1,21 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + DYNAMISK NY KATT HOFTE RESERVERT AM + BITA + DYNAMISK NY KATT HOFTE RESERVE + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-name-long-change/prep.xml b/K6/testdata/register/ER-data/testcase-name-long-change/prep.xml new file mode 100644 index 00000000..b0e567c2 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-name-long-change/prep.xml @@ -0,0 +1,27 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + DYNAMISK BRA KATT HOFTE RESERVERT A + MBITA + DYNAMISK BRA KATT HOFTE RESE + + + 1234 + NO + 0301 + Testveien 30 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-name-short-change/change-name.xml b/K6/testdata/register/ER-data/testcase-name-short-change/change-name.xml new file mode 100644 index 00000000..672eb28c --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-name-short-change/change-name.xml @@ -0,0 +1,20 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC ENK OPPDATERT + ER SYNC ENK OPPDATERT + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-name-short-change/prep.xml b/K6/testdata/register/ER-data/testcase-name-short-change/prep.xml new file mode 100644 index 00000000..e59955f1 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-name-short-change/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC ENK + ER SYNC ENK + + + 1234 + NO + 0301 + Testveien 1 + + + N + 1 + 12864421537 + Elise + Testperson + 1234 + Testveien 29 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-org-coupling/add-revi-coupling.xml b/K6/testdata/register/ER-data/testcase-org-coupling/add-revi-coupling.xml new file mode 100644 index 00000000..552aac77 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-org-coupling/add-revi-coupling.xml @@ -0,0 +1,21 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + N + 1 + 316289231 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-org-coupling/prep-accounting-firm.xml b/K6/testdata/register/ER-data/testcase-org-coupling/prep-accounting-firm.xml new file mode 100644 index 00000000..36e480d4 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-org-coupling/prep-accounting-firm.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC REVISJON AS + ER SYNC REVISJON AS + + + 0150 + NO + 0301 + Revisorveien 1 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-org-coupling/prep.xml b/K6/testdata/register/ER-data/testcase-org-coupling/prep.xml new file mode 100644 index 00000000..416b0779 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-org-coupling/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC COUPLING AS + ER SYNC COUPLING AS + + + 0150 + NO + 0301 + Testveien 30 + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-padr-change/change-padr.xml b/K6/testdata/register/ER-data/testcase-padr-change/change-padr.xml new file mode 100644 index 00000000..b207f15a --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-padr-change/change-padr.xml @@ -0,0 +1,22 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 0160 + NO + 0301 + Postboks 123 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-padr-change/prep.xml b/K6/testdata/register/ER-data/testcase-padr-change/prep.xml new file mode 100644 index 00000000..0ab36344 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-padr-change/prep.xml @@ -0,0 +1,76 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + N + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-regn-revi-change/change-regn-revi.xml b/K6/testdata/register/ER-data/testcase-regn-revi-change/change-regn-revi.xml new file mode 100644 index 00000000..003ba9bb --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-regn-revi-change/change-regn-revi.xml @@ -0,0 +1,36 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + J + 1 + 316289231 + + + N + 1 + 316289339 + + + J + 1 + 316289231 + + + N + 1 + 316289339 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-accounting-firm.xml b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-accounting-firm.xml new file mode 100644 index 00000000..d7ae32fd --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-accounting-firm.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC REVISJON AS + ER SYNC REVISJON AS + + + 0150 + NO + 0301 + Revisorveien 1 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-new-accounting-firm.xml b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-new-accounting-firm.xml new file mode 100644 index 00000000..fea027e1 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep-new-accounting-firm.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC NY REVISJON AS + ER SYNC NY REVISJON AS + + + 0150 + NO + 0301 + Revisorveien 2 + + + N + 1 + 26917031273 + Erik Test + Testperson + 0150 + Testveien 14 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-regn-revi-change/prep.xml b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep.xml new file mode 100644 index 00000000..deddc55c --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-regn-revi-change/prep.xml @@ -0,0 +1,47 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 316289231 + + + N + 1 + 316289231 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-board-member/prep.xml b/K6/testdata/register/ER-data/testcase-remove-board-member/prep.xml new file mode 100644 index 00000000..e7d5c071 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-board-member/prep.xml @@ -0,0 +1,59 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + N + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-board-member/remove-board-member.xml b/K6/testdata/register/ER-data/testcase-remove-board-member/remove-board-member.xml new file mode 100644 index 00000000..de0955ff --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-board-member/remove-board-member.xml @@ -0,0 +1,49 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + N + 1 + 07855812899 + Ola Test + Testperson + 0150 + Testveien 12 + NO + L + + + J + 2 + 10886039447 + Kari Marit + Testperson + 0150 + Testveien 13 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-fmva/prep-parent-org.xml b/K6/testdata/register/ER-data/testcase-remove-fmva/prep-parent-org.xml new file mode 100644 index 00000000..aab37969 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-fmva/prep-parent-org.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC AS + ER SYNC AS + + + 0150 + NO + 0301 + Testveien 10 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-fmva/prep.xml b/K6/testdata/register/ER-data/testcase-remove-fmva/prep.xml new file mode 100644 index 00000000..9da9287e --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-fmva/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC BEDR + ER SYNC BEDR + + + 0150 + NO + 0301 + Testveien 10 + + + BFLA + + + 22334466 + + + N + 1 + 316289215 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-fmva/remove-fmva.xml b/K6/testdata/register/ER-data/testcase-remove-fmva/remove-fmva.xml new file mode 100644 index 00000000..64052c2a --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-fmva/remove-fmva.xml @@ -0,0 +1,17 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-paat/prep.xml b/K6/testdata/register/ER-data/testcase-remove-paat/prep.xml new file mode 100644 index 00000000..4474020b --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-paat/prep.xml @@ -0,0 +1,40 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC PAAT AS + ER SYNC PAAT AS + + + 0150 + NO + 0301 + Testveien 60 + + + J + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-remove-paat/remove-paat.xml b/K6/testdata/register/ER-data/testcase-remove-paat/remove-paat.xml new file mode 100644 index 00000000..63c34100 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-remove-paat/remove-paat.xml @@ -0,0 +1,17 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-set-konk/prep.xml b/K6/testdata/register/ER-data/testcase-set-konk/prep.xml new file mode 100644 index 00000000..fedd3e90 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-set-konk/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC KONK AS + ER SYNC KONK AS + + + 0150 + NO + 0301 + Testveien 50 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-set-konk/set-konk.xml b/K6/testdata/register/ER-data/testcase-set-konk/set-konk.xml new file mode 100644 index 00000000..79ce4cd2 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-set-konk/set-konk.xml @@ -0,0 +1,19 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 20260512 + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-set-oppl/prep.xml b/K6/testdata/register/ER-data/testcase-set-oppl/prep.xml new file mode 100644 index 00000000..1fb02743 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-set-oppl/prep.xml @@ -0,0 +1,37 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + ER SYNC OPPL AS + ER SYNC OPPL AS + + + 0150 + NO + 0301 + Testveien 51 + + + N + 1 + 02895823468 + Anne + Testperson + 0150 + Testveien 11 + NO + L + + + + ]]> + + + diff --git a/K6/testdata/register/ER-data/testcase-set-oppl/set-oppl.xml b/K6/testdata/register/ER-data/testcase-set-oppl/set-oppl.xml new file mode 100644 index 00000000..d71f07d5 --- /dev/null +++ b/K6/testdata/register/ER-data/testcase-set-oppl/set-oppl.xml @@ -0,0 +1,19 @@ + + + + + ${soapErUsername} + ${soapErPassword} + + + + + + 20260512 + + + + ]]> + + +