-
Notifications
You must be signed in to change notification settings - Fork 12
fix array fqdn bug and add unit tests for JsonNodeMapper #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
8b82746
test: add comprehensive JsonNodeMapper tests and fix fqdn creation fo…
9ac6b33
refactor: simplify JsonNodeMapper with helper methods and improve tes…
4df3e51
refactor: improve JsonNodeMapper test readability with external test …
c101978
refactor: improve JsonNodeMapper test readability with external test …
58e4d64
Merge branch 'add-element-identifiers' of https://github.com/bettyand…
e077d10
revert: restore original ObjectDiffCheckerServiceTest.kt and resource…
9f2a449
cleanup
f947ba0
Merge branch 'add-element-identifiers' of https://github.com/bettyand…
aede380
test: add test cases for list order changes in nested and deeply nest…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
263 changes: 263 additions & 0 deletions
263
...st/kotlin/com/lowes/auditor/client/infrastructure/frameworks/mapper/JsonNodeMapperTest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,263 @@ | ||
| package com.lowes.auditor.client.infrastructure.frameworks.mapper | ||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper | ||
| import com.lowes.auditor.core.entities.domain.Element | ||
| import com.lowes.auditor.core.entities.domain.EventType | ||
| import io.kotest.core.spec.style.BehaviorSpec | ||
| import io.kotest.matchers.nulls.shouldNotBeNull | ||
| import io.kotest.matchers.shouldBe | ||
|
|
||
| /** | ||
| * Unit Tests for [JsonNodeMapper] | ||
| */ | ||
| class JsonNodeMapperTest : BehaviorSpec({ | ||
| val objectMapper = ObjectMapper() | ||
| val fqcn = "com.example.Test" | ||
|
|
||
| Given("a simple JSON object with primitive values") { | ||
| val simpleJson = | ||
| """ | ||
| { | ||
| "id": 1, | ||
| "name": "Test", | ||
| "active": true | ||
| } | ||
| """.trimIndent() | ||
|
|
||
| val jsonNode = objectMapper.readTree(simpleJson) | ||
|
|
||
| When("converting to elements with CREATED event type") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.CREATED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should create elements with correct FQDNs and values") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/simpleCreated.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by name for consistent comparison | ||
| val sortedActual = elements.sortedBy { it.name } | ||
| val sortedExpected = expectedElements.sortedBy { it.name } | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
| } | ||
| } | ||
|
|
||
| When("converting to elements with DELETED event type") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.DELETED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should set previousValue instead of updatedValue") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/simpleDeleted.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by name for consistent comparison | ||
| val sortedActual = elements.sortedBy { it.name } | ||
| val sortedExpected = expectedElements.sortedBy { it.name } | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Given("a JSON object with nested objects") { | ||
| val nestedJson = | ||
| """ | ||
| { | ||
| "id": 1, | ||
| "name": "Test", | ||
| "address": { | ||
| "street": "123 Main St", | ||
| "city": "Anytown", | ||
| "zip": "12345" | ||
| } | ||
| } | ||
| """.trimIndent() | ||
|
|
||
| val jsonNode = objectMapper.readTree(nestedJson) | ||
|
|
||
| When("converting to elements") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.CREATED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should handle nested objects correctly") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/nestedCreated.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by name and fqdn for consistent comparison | ||
| val sortedActual = elements.sortedWith(compareBy({ it.name }, { it.metadata?.fqdn })) | ||
| val sortedExpected = expectedElements.sortedWith(compareBy({ it.name }, { it.metadata?.fqdn })) | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Given("a complex JSON object with arrays and nested objects") { | ||
| val complexJson = | ||
| """ | ||
| { | ||
| "id": 1, | ||
| "name": "Test User", | ||
| "addresses": [ | ||
| { | ||
| "type": "home", | ||
| "street": "123 Main St", | ||
| "city": "Anytown" | ||
| }, | ||
| { | ||
| "type": "work", | ||
| "street": "456 Business Ave", | ||
| "city": "Businesstown" | ||
| } | ||
| ], | ||
| "preferences": { | ||
| "notifications": true, | ||
| "theme": "dark", | ||
| "favoriteCategories": ["tech", "books", "music"] | ||
| } | ||
| } | ||
| """.trimIndent() | ||
|
|
||
| val jsonNode = objectMapper.readTree(complexJson) | ||
|
|
||
| When("converting complex object to elements") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.CREATED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should handle all nested structures correctly") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/complexCreated.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by fqdn for consistent comparison | ||
| val sortedActual = elements.sortedBy { it.metadata?.fqdn } | ||
| val sortedExpected = expectedElements.sortedBy { it.metadata?.fqdn } | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Given("a JSON object with various array structures") { | ||
| val nestedArrayJson = | ||
| """ | ||
| { | ||
| "matrix": [ | ||
| [1, 2, 3], | ||
| [4, 5, 6], | ||
| [7, 8, 9] | ||
| ], | ||
| "nested": { | ||
| "deepArray": [ | ||
| [ | ||
| {"id": 1, "values": ["a", "b"]}, | ||
| {"id": 2, "values": ["c", "d"]} | ||
| ], | ||
| [ | ||
| {"id": 3, "values": ["e", "f"]} | ||
| ] | ||
| ] | ||
| }, | ||
| "simpleArray": [ | ||
| {"id": 1, "name": "Item 1"}, | ||
| {"id": 2, "name": "Item 2"} | ||
| ] | ||
| } | ||
| """.trimIndent() | ||
|
|
||
| val jsonNode = objectMapper.readTree(nestedArrayJson) | ||
|
|
||
| When("converting nested arrays to elements") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.CREATED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should handle all levels of nested arrays correctly") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/nestedArrayCreated.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by fqdn for consistent comparison | ||
| val sortedActual = elements.sortedBy { it.metadata?.fqdn } | ||
| val sortedExpected = expectedElements.sortedBy { it.metadata?.fqdn } | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Given("a JSON object with edge case values") { | ||
| val edgeCaseJson = | ||
| """ | ||
| { | ||
| "nullValue": null, | ||
| "emptyString": "", | ||
| "zero": 0, | ||
| "falseValue": false, | ||
| "emptyObject": {}, | ||
| "emptyArray": [] | ||
| } | ||
| """.trimIndent() | ||
|
|
||
| val jsonNode = objectMapper.readTree(edgeCaseJson) | ||
|
|
||
| When("converting edge case values to elements") { | ||
| val elements = | ||
| JsonNodeMapper.toElement(jsonNode, EventType.CREATED, fqcn) | ||
| .collectList() | ||
| .block() | ||
|
|
||
| Then("should handle all edge cases correctly") { | ||
| elements.shouldNotBeNull() | ||
|
|
||
| val expectedElements: List<Element> = | ||
| objectMapper.readValue( | ||
| javaClass.getResource("/edgeCaseCreated.json").readBytes(), | ||
| Array<Element>::class.java, | ||
| ).toList() | ||
|
|
||
| // Sort both lists by name for consistent comparison | ||
| val sortedActual = elements.sortedBy { it.name } | ||
| val sortedExpected = expectedElements.sortedBy { it.name } | ||
|
|
||
| sortedActual shouldBe sortedExpected | ||
|
|
||
| // Explicitly verify empty objects and arrays are filtered out | ||
| elements.find { it.name == "emptyObject" } shouldBe null | ||
| elements.find { it.name == "emptyArray" } shouldBe null | ||
| } | ||
| } | ||
| } | ||
| }) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.