UseJunior Book a Demo

safe-docx · Reject Tracked Changes

Tracked insertion removal

When rejecting tracked insertions from a WordprocessingML document, inserted content must be removed without changing the original paragraph content. A tracked insertion is represented by a <w:ins> wrapper around the content that was added, so rejecting the change means removing that wrapper and its children.

rejectChanges applies that rule while walking the document body. For inserted content inside a paragraph, the removal also updates the document state that paragraph-text queries read after the mutation.[1]

Below is a test scenario of the inserted-content removal case of rejectChanges: removing a tracked insertion from a paragraph leaves the original paragraph content.

The scenario

Given a document with original text and an insertion,
When rejectChanges is called,
Then

  • result.insertionsRemoved is 1.
  • the paragraph text is ['Original'].

Test fixture

The fixture builds a single paragraph with original text followed by a tracked insertion. That setup lets the scenario check both the removal count and the paragraph text that remains after the document is mutated.

Below is the test fixture code.

test('should remove inserted content', async ({ given, when, then }: AllureBddContext) => {
  let doc: Document;
  let result: ReturnType<typeof rejectChanges>;

  await given('a document with original text and an insertion', async () => {
    doc = makeDoc(
      '<w:p>' +
        '<w:r><w:t>Original</w:t></w:r>' +
        '<w:ins w:author="Author" w:date="2024-01-01T00:00:00Z">' +
          '<w:r><w:t> added</w:t></w:r>' +
        '</w:ins>' +
      '</w:p>',
    );
  });

  await when('rejectChanges is called', async () => {
    result = rejectChanges(doc);
  });

  await then('inserted content is removed', async () => {
    expect(result.insertionsRemoved).toBe(1);
    expect(getAllParagraphTexts(doc)).toEqual(['Original']);
  });
});

Expected outcome

The scenario asserts one return-field value and one post-mutation document query. The outcome is the pair of checks, because the paragraph text is read from the document after rejectChanges has changed it.

Below is the result that rejectChanges is expected to return for this scenario.

expect(result.insertionsRemoved).toBe(1);
expect(getAllParagraphTexts(doc)).toEqual(['Original']);

The result.insertionsRemoved field is expected to be 1, because the fixture contains one <w:ins> element. The getAllParagraphTexts(doc) query is expected to return ['Original'], because rejecting the tracked insertion removes the added paragraph content and leaves the original run element (i.e., a <w:r> container for text or related run-level markup) in place.[2]