Skip to content

fix: Send full nested object on update - #141

Merged
Lucia (QixiaLu) merged 8 commits into
microsoft:mainfrom
QixiaLu:fix_update_nested_objects
Aug 5, 2026
Merged

fix: Send full nested object on update#141
Lucia (QixiaLu) merged 8 commits into
microsoft:mainfrom
QixiaLu:fix_update_nested_objects

Conversation

@QixiaLu

@QixiaLu Lucia (QixiaLu) commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Problem

DiffObject was computing a minimal diff at every level, so changing one sub-field produced a partial object. Updating claimsMatchingExpression.value on a federated identity credential sent only value, and Graph reset languageVersion to its default.

Fix

DiffObject now emits the entire object whenever a nested object changes. Minimal-diff semantics are kept at the top level for scalars and arrays, which do follow JSON Merge PATCH.

Change detection routes through DiffObject rather than a raw reflect.DeepEqual, so IgnoreCasing and IgnoreMissingProperty are honoured — an object whose only difference is a recased string or a "****" placeholder read back from Graph is not re-sent.

fix issue #137

Test

acctest result: https://dev.azure.com/azclitools/internal/_build/results?buildId=334251&view=logs&j=ca395085-040a-526b-2ce8-bdc85f692774&t=e722f262-b132-5c61-9453-a20c0496ffb3

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts JSON diffing for msgraph_resource PATCH updates to avoid Microsoft Graph resetting omitted sub-fields inside complex (nested) types by sending the full nested object whenever it changes.

Changes:

  • Update DiffObject to return full nested objects for changed object-valued properties (while keeping top-level minimal PATCH behavior).
  • Centralize “redacted string” detection and extend unit tests to cover complex-type patching and redacted/casing no-op diffs.
  • Add an acceptance test covering updates to federatedIdentityCredentials.claimsMatchingExpression and document the fix in the changelog.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
internal/utils/json.go Changes DiffObject to emit full nested objects on change; factors out redacted-string detection helper.
internal/utils/json_test.go Updates/extends tests to validate full-object patching for nested complex types and no-op diffs for redacted/casing-only differences.
internal/services/msgraph_resource_test.go Adds acceptance coverage for updating claimsMatchingExpression without resetting sibling fields.
CHANGELOG.md Documents the bug fix and links to issue #137.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/utils/json.go
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (2)

internal/utils/json.go:242

  • DiffObject now sends the full nested object by assigning res[key] = newVal when any child differs. This bypasses the leaf-level IgnoreMissingProperty/redaction handling (e.g., "****" / "" / ""), so a nested object that changed in one field can still write back redacted placeholder values in other fields, contradicting isRedactedString's contract.
				if oldVal, ok := oldValue[key]; ok {
					if d := DiffObject(oldVal, newVal, option); d != nil {
						res[key] = newVal
					}

internal/utils/json_test.go:357

  • TestDiffObject covers the case where a complex type differs only by a redacted leaf (expecting nil), but it does not cover the more problematic case where a complex type changes in a real field while also containing a redacted placeholder sibling. With the new "send full object" behavior, that scenario can regress into sending the placeholder back unless explicitly tested.
		{
			name: "complex type differing only by redacted leaf -> no change",
			old: map[string]interface{}{
				"credentials": map[string]interface{}{"displayName": "cred", "secretText": "s3cret"},
			},

@gerrytan Gerry Tan (gerrytan) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx Lucia (@QixiaLu) , the PR looks good. Just small check: can you please check if the acctest failure TestAcc_ResourceMoveState_DirectoryRoleMember is related to this changes at all? This is passing in main (maybe a flake).

@QixiaLu

Copy link
Copy Markdown
Collaborator Author

Thanks Gerry Tan (@gerrytan) for reviewing! I have merged Main into this branch, and fix an issue in the new test (seems like an Azure API validation change....).

The final test result (https://dev.azure.com/azclitools/internal/_build/results?buildId=335481&view=logs&j=ca395085-040a-526b-2ce8-bdc85f692774&t=e722f262-b132-5c61-9453-a20c0496ffb3) is consistent with what in the main. Could I get another review when you get a chance? Thank you!

@gerrytan Gerry Tan (gerrytan) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx Lucia (@QixiaLu) , approved, the PR looks good now.

@QixiaLu
Lucia (QixiaLu) merged commit 773e084 into microsoft:main Aug 5, 2026
10 of 12 checks passed
@QixiaLu
Lucia (QixiaLu) deleted the fix_update_nested_objects branch August 5, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants