====== draw.io plugin - manual test protocol ======

This page is seeded by the dev docker image. Everything below is either already
covered by an automated test (marked //auto//) or needs a human - the draw.io
editor itself is a third-party iframe that cannot be driven from CI.

Work top to bottom. Each section says what you should see.

===== 1. New diagram, then edit it again =====

A diagram that does not exist yet shows a placeholder. Click it: the draw.io
editor opens. Draw a box, **Save**, then close the editor. The placeholder is
replaced by your drawing. Click the drawing: the editor reopens **with your box
still in it** (the diagram is loaded back from the PNG).

{{drawio>test:fresh_diagram}}

===== 2. Drafts stay with their own diagram (issue #26) =====

This is the bug that could destroy a diagram, so it is worth the two minutes.

  - Open diagram 1 above, change something, close the editor **without saving**.
  - Open the diagram below.
  - It must open **empty**. If it offers to restore "a version of this diagram",
    the fix regressed - that draft belongs to diagram 1.

{{drawio>test:second_diagram}}

===== 3. SVG diagrams =====

The dev wiki is configured with ''toolbar_possible_extension = png,svg''.
The toolbar button becomes a picker with a PNG and an SVG variant.

{{drawio>test:vector_diagram.svg}}

===== 4. Empty diagram name (issue #15) //auto// =====

Must render a red italic error, not a clickable placeholder that creates an
unusable diagram.

{{drawio>test:}}

===== 5. Namespace placeholders (issue #31) //auto// =====

''@NS@'' is the current namespace, ''@PAGE@'' (alias ''@FILE@'') the current
page name, so the same syntax can be pasted onto many pages. On this page it
resolves to ''drawio_diagram''.

{{drawio>@NS@:@PAGE@_diagram}}

===== 6. Link to the editor, no image (issue #41) //auto// =====

A text link that opens the editor for diagram 1. The image itself is not shown,
so nobody opens the editor by misclicking the picture.

{{drawio>test:fresh_diagram?linkonly|edit graph}}

===== 7. Size and title (issue #23) //auto// =====

Width only, then width and height. Both have "mouse-over text" as tooltip, and
both still shrink instead of overflowing when you narrow the browser window.

{{drawio>test:fresh_diagram?200|mouse-over text}}

{{drawio>test:fresh_diagram?200x100|mouse-over text}}

===== 8. Media manager usage (issue #10) =====

  - Open [[?do=media&ns=test|the media manager]] and select ''test:fresh_diagram.png''.
  - The //References for// panel lists the pages using it - this page among them.
  - If it says nothing was found, the search index has not caught up yet.
    Reload this page once (that runs the indexer) and look again.

===== 9. Empty diagram stays repairable (issue #66 comment) =====

Save a diagram without drawing anything. draw.io writes an empty file. You must
still see the placeholder and still be able to click it to edit - before the
fix, the page showed nothing clickable and the diagram was stuck forever.

===== 10. Git backup hook (issue #36) =====

Only testable with the [[https://www.dokuwiki.org/plugin:gitbacked|gitbacked]]
plugin installed: saving a diagram now fires ''MEDIA_UPLOAD_FINISH'', so the
PNG is committed like any uploaded media. Automated tests assert the event and
its payload; an actual gitbacked install was not part of the test.

===== 11. Edit button in the media manager (issue #16) =====

A diagram that no page (any longer) references used to be uneditable: nothing
in the media manager could open it. There is now an **Edit with draw.io**
button in the file detail panel.

  - Open [[?do=media&ns=test|the media manager]] and select
    ''test:fresh_diagram.png'' (draw diagram 1 in section 1 above first, if you
    have not already, so the file exists).
  - In the detail panel on the right, below the preview image, you should see
    an **Edit with draw.io** button alongside the existing *Delete* / *Upload
    new version* buttons.
  - Click it: the draw.io editor opens on that diagram, exactly like clicking
    the diagram on this page does. Save and close - the preview image in the
    media manager updates.
  - Click a non-diagram file (anything not ''.png''/''.svg''): the button must
    not appear.

This also indirectly checks issue #16 itself: opening the media manager no
longer breaks other plugins' JavaScript (see the plugin's own script.js for
why - DokuWiki concatenates every plugin's script into one file, and this
plugin used to throw at load time whenever the media manager's page did not
provide its config, silently breaking whatever plugin's script came after it
alphabetically).
===== 12. ODT export (issue #7) =====

The dev image bakes the third-party [[https://www.dokuwiki.org/plugin:odt|odt
plugin]] into ''plugins.core'' (see ''docker/Dockerfile''), so it is already
installed and enabled here - nothing to set up.

  - Draw something in diagram 1 at the top of this page (or any diagram with a
    real image behind it).
  - Open [[?do=export_odt&id=drawio|this page's ODT export]] (or use the export
    icon DokuWiki's page tools add once the odt plugin is active) and save the
    file.
  - An ''.odt'' is a zip. Unzip it and check two things:
    - ''unzip -l export.odt'' lists a file under ''Pictures/'' - your diagram.
    - ''unzip -p export.odt content.xml'' contains a ''<draw:image
      xlink:href="Pictures/...">'' pointing at that same file.
  - A diagram that does not exist yet (like ''test:second_diagram'' above, if
    you have not opened it) must simply be absent from the export - no broken
    image, no PHP warning in the container's ''docker compose logs''.
  - ''?linkonly'' diagrams (section 6) are embedded as images here too: a
    printed document has no editor to click, so showing nothing would be
    worse than showing the picture.

===== 13. The diagram source lives next to the image =====

A diagram used to exist only as an exported picture with its XML hidden inside
it. Anything that rewrites media - an image optimiser, a format conversion, a
backup that re-encodes - threw that away and the diagram became a flat picture
nobody could edit. The XML is now stored beside the image as an ordinary media
file: ''test:fresh_diagram.png'' gets ''test:fresh_diagram.drawio''.

  - Draw and save diagram 1 at the top of this page.
  - Open [[?do=media&ns=test|the media manager]]: next to the ''.png'' there is
    now a ''.drawio'' of the same name. It is a plain media file, so the same
    namespace ACL governs both - there is no second permission model.
  - **The check that matters:** with the editor closed, download the ''.png''
    and upload it again through //Upload new version// after running it through
    any tool that strips metadata (or simply replace it with an unrelated PNG).
    Before this change the diagram was gone for good. Now click the diagram:
    the uploaded image is newer than the source, so it is what opens (that is
    deliberate - see below) - but delete the image and restore the previous
    revision, and your diagram is still editable.
  - **An old diagram still works.** Any diagram saved before this release has
    no ''.drawio''. It must open exactly as it always did, from the image, and
    it must grow its ''.drawio'' the first time you save it. Nothing converts
    anything on read.
  - **Restoring an old revision must still mean something.** With
    ''mediarevisions'' on, save a diagram twice, then restore the first
    revision in the media manager. Click the diagram: you must get the
    //restored// drawing, not the newest one. The plugin prefers the ''.drawio''
    source, except when the image is the newer of the two - which is exactly
    what a restore (or a media manager upload) makes it.

Known wart: the media manager now lists twice as many files in a diagram
namespace - the same thing the ''.png.draft'' scratch files have always done
there. Hiding them would make them undeletable, so they are left visible;
DokuWiki has no mime type for ''.drawio'', so it is never rendered inline and
''fetch.php'' only ever offers it as a download.

===== 14. A diagram's identity is its name, not its extension =====

''test:plan.png'' and ''test:plan.svg'' are **two renderings of the same
diagram**, not two diagrams that happen to share a name. Both read and write
the very same ''test:plan.drawio''; editing either one edits that diagram, and
saving either overwrites the shared source. This is deliberate, not an
accident of the naming scheme - see ''helper.php'''s ''sourceID()'' for the
full reasoning.

  - Draw diagram 1 at the top of this page (''test:fresh_diagram.png''), then
    open [[?do=media&ns=test|the media manager]] and note ''test:fresh_diagram.drawio''.
  - Add ''{{drawio>test:fresh_diagram.svg}}'' to a scratch page and open it:
    it starts from the **same** source, because it is the same diagram in a
    different format - not a blank one.
  - Saving one format never regenerates the other format's image file. If
    only the ''.png'' exists, saving the ''.svg'' does not create or touch it
    - the ''.png'' is left exactly as it was until someone next saves *in
    that format*. Nothing here writes a file nobody asked for.

**The one genuine hazard:** if a wiki already has ''plan.png'' and
''plan.svg'' as two genuinely *different* diagrams - both drawn before this
plugin stored a shared source, so each still only has its own XML embedded in
its own image - that difference is silently erased the first time **either**
one is next saved. Whichever is saved first writes ''plan.drawio'', and from
then on both formats open from it, not from what used to be their own
picture. There is no way for the plugin to detect this case (both are just
image bytes); if a wiki has same-named diagrams like this, rename one of them
before either is opened for editing again.

===== 15. Two people editing the same diagram (advisory lock) =====

Two tabs (or two people) editing the same diagram used to mean the second
save silently won and the first person's work vanished, with no warning to
either of them. This is now an advisory warning, not a hard lock - the same
posture DokuWiki itself takes with pages: you are told someone else may be
editing it, and you can carry on anyway. Nobody is ever locked out of their
own diagram by a tab someone forgot to close.

**How long a lock lasts, in plain words:** opening a diagram takes the lock
and an open editor keeps renewing it (roughly every 5 minutes, by default,
regardless of whether you have actually drawn anything - see below for why).
**Closing the editor does not release it.** The lock simply expires on its
own after the wiki's configured ''locktime'' (15 minutes by default) of no
renewal. That means after you close an editor cleanly, someone else opening
the same diagram can still be told "opened by you N minutes ago" for up to
that long - a stale warning, not a wrong one; treat it as "recently", not
"right now". This is a deliberate trade: the alternative (releasing the lock
on close) let one tab silently delete a *different* tab's or a different
person's still-active protection just by being closed, which is worse than
an occasional stale warning for a warning nobody is blocked by.

**To see a collision:**

  - In one browser, log in as one user and open [[?do=media&ns=test|the media
    manager]], select ''test:fresh_diagram.png'' and click **Edit with
    draw.io** (or click the diagram in section 1 above). Leave the editor
    open - do not draw anything yet.
  - In a **second browser** (or a private/incognito window, so it is a
    different login) as a **different user**, open the very same diagram.
  - You must see a message naming the first user and roughly how long ago
    they opened it, e.g. "This diagram was opened by alice 1 minute(s) ago
    and may still be open there. Continue anyway?" - then the editor opens
    regardless of what you do about the message. It is information, not a
    lock: both users can draw and save; whoever saves last wins, same as
    before this feature, just no longer a silent surprise. Note this works
    even though the first user has not drawn anything yet - the lock is kept
    alive by the open editor itself, not by editing.
  - Reopening the **same** diagram yourself, in a second tab as the **same**
    logged-in user, must **not** warn.

**To see the lock expire on its own:** close the first editor (or just leave
it idle), then wait past the wiki's configured ''locktime'' (15 minutes by
default) before opening the diagram as the second user. The warning must be
gone by then. Waiting the *first* user's session out while their tab is still
open should not happen in practice - the open editor renews the lock every
few minutes on its own, well inside ''locktime'' - but closing it is what
starts the countdown, per the paragraph above.

**A diagram's two renderings share one lock:** open ''test:plan.png'' as one
user, then ''test:plan.svg'' as another (see section 14 above for why these
are the same diagram) - the second user must be warned about the first, even
though the filename extension differs. Closing either tab must not affect the
other's protection.

Anonymous editing: on a wiki that allows edits without logging in, this reuses
exactly the identity DokuWiki's own page lock uses for an anonymous editor -
IP address plus browser session - so two different anonymous visitors are
correctly treated as different people (and warn each other), while two tabs
of the very same anonymous visitor's own session do not warn each other.
===== 16. Bulk-converting old diagrams (the admin task) =====

Section 13 above shows a diagram gaining its source lazily, one save at a
time. There is also an admin task that gives *every* diagram a source in one
pass, for someone who wants their whole wiki protected right now.

  - Upload a PNG that has a draw.io ''mxfile'' XML chunk embedded but no
    ''.drawio'' sibling yet (any export from an older version of this plugin,
    or a real draw.io export, works) into a scratch namespace, e.g.
    ''seedtest:old_diagram.png''. Also upload a plain, unrelated PNG as
    ''seedtest:not_a_diagram.png'' with no embedded XML.
  - Open [[?do=admin&page=drawio|Admin → Draw.io: convert old diagrams]].
    This is only visible/reachable to a superuser, not a manager.
  - You land on a **dry run**: it reports how many diagrams were found, how
    many already have a source, and how many do not yet - and, below that, a
    per-diagram table. ''seedtest:old_diagram.png'' should read "source can be
    recovered from the image"; ''seedtest:not_a_diagram.png'' should read "no
    draw.io XML found in the image - cannot be recovered". Nothing has been
    written yet - check the media manager, there is still no
    ''seedtest:old_diagram.drawio''.
  - Click **Convert this batch**. The table now shows "source written" for
    ''seedtest:old_diagram.png''; the media manager now lists
    ''seedtest:old_diagram.drawio'' next to it. ''seedtest:not_a_diagram.png''
    is unchanged - there was nothing to recover.
  - Click the diagram on a page (or re-open it from the media manager's
    **Edit with draw.io** button, section 11): it must load correctly, now
    from its new source rather than from the image.
  - Run the task again (dry run first): ''seedtest:old_diagram.png'' now
    reads "already has a source - left untouched", and clicking **Convert
    this batch** again must not change the file or its content - an existing
    source is never overwritten.

===== 17. Configurable editor interface (ui=atlas was hardcoded) =====

The editor's interface (kennedy/min/atlas/dark/sketch/simple) used to be
hardcoded to ''atlas''. It is now a config setting.

  - Open [[?do=admin&page=config|Admin → Configuration Settings]] and find
    //Interface style of the draw.io editor// under the drawio plugin's
    settings. Set it to ''min'' and save.
  - Open diagram 1 at the top of this page: the editor must open in the
    Minimal interface, not Atlas.
  - The setting only offers the six values draw.io's ''ui'' parameter
    actually understands - there is no free-text field to get this wrong in.
===== 18. The source survives delete and rename =====

Section 13 is what keeps a diagram's XML alive across an upload that
rewrites the image. It did nothing, until now, about the media manager's own
delete and rename - deleting ''plan.png'' left ''plan.drawio'' behind
forever, and renaming it left the source under the old name.

  - Draw and save a diagram, e.g. ''seedtest:deleteme.png'' - check the
    media manager shows ''seedtest:deleteme.drawio'' next to it (section 13).
  - Delete ''seedtest:deleteme.png'' in the media manager. **Both** files
    must disappear - the source goes with the image, deliberately: "delete"
    means the diagram is gone, not "gone except for a file nobody asked to
    keep". This is not as final as it sounds - with ''mediarevisions'' on
    (the default) both files went to the attic, the same as any deleted
    media, and the page's //Old revisions// / //History// panel for
    ''seedtest:deleteme.drawio'' lists the deleted revision with a working
    **Restore this old version**.
  - Redraw it, this time as **two** renderings sharing one source: save
    ''seedtest:shared.png'', then add ''{{drawio>seedtest:shared.svg}}'' to a
    scratch page and open it once (section 14 - both read the same
    ''seedtest:shared.drawio''). Delete only ''seedtest:shared.png''. The
    source must **stay** - ''seedtest:shared.svg'' is still there and still
    needs it. Now delete ''seedtest:shared.svg'' too: the source must
    **now** disappear, since nothing needs it any more.
  - Delete ''seedtest:deleteme.drawio'' directly, on a diagram whose image is
    still there. The image must be left alone - it still opens, from its own
    embedded XML, exactly as every diagram did before source-of-truth
    existed; deleting a small text file must never reach out and delete
    somebody's picture.
  - Rename/move a diagram (needs the third-party
    [[https://www.dokuwiki.org/plugin:move|move]] plugin - not part of this
    plugin, but the only way a real wiki renames media at all). Draw and save
    ''seedtest:before.png'', then rename it to ''seedtest:after.png'' (or
    into a different namespace). ''seedtest:before.drawio'' must be gone and
    ''seedtest:after.drawio'' must exist with the same content - open the
    diagram afterwards and confirm your drawing is still there. Same
    two-renderings rule as delete: if ''seedtest:before.svg'' still exists
    after renaming only the ''.png'', the source must stay put for it.

===== 19. Diagram text is findable in search =====

A diagram's labels used to be invisible to DokuWiki's own search - a page
whose architecture diagram says "firewall" could not be found by searching
for "firewall". The XML now on disk changes that.

  - Draw a diagram with a labelled shape containing a distinctive word that
    appears **nowhere else on the page**, e.g. ''zzsearchable'', and save it
    on a page, e.g. ''seedtest:searchpage''.
  - Search for ''zzsearchable'' ([[?do=search&q=zzsearchable|search now]]).
    If nothing is found, the indexer has not caught up yet - reload
    ''seedtest:searchpage'' once (that queues it) or run
    ''bin/indexer.php'' - then search again. The page must now be found,
    even though the word exists only inside the diagram, not in the page's
    own wikitext.
  - **The part that must not work:** put the same kind of diagram on a
    **publicly readable** page, but store the diagram itself in a namespace
    your ACL denies to ordinary readers (e.g. draw
    ''secret:hiddenlabel.png'' with a distinctive word in it, restricted by
    an ACL rule such as ''secret:* @ALL 0'', and reference it from a public
    page). Reindex, then search for that word as a normal (non-admin) user.
    It must **not** be found - a page anyone can read must never hand out a
    restricted diagram's text through search just because it embeds it.
