* test(labels): share InMemory/EF store conformance scenarios
Add one abstract Labels store suite and run it against InMemory and
EF Core (SQLite) so tenant isolation, NormalizedName uniqueness,
cascade delete, ReplaceAsync, and association lookups stay aligned.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* test(labels): drop provider-specific uniqueness and paging asserts
SaveMany name swaps trip EF BulkUpsert unique indexes, and Memory
ToPage counts after Skip/Take. Keep the shared matrix on contracts
both InMemory and EF/SQLite honor.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* test(labels): map conformance matrix to the #8091 lock list
Keep one scenario per issue invariant so the InMemory/EF harness stays
small and readable: cascade delete, ReplaceAsync, association
finds/deletes, ListAsync order/paging, tenant stamp/isolation, and
per-tenant NormalizedName uniqueness.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* test(labels): cover cross-tenant lookup conformance
* test(labels): use Path.Join for sqlite fixture
* test(labels): lock ID-only ReplaceAsync and SaveMany tenant stamp
Vary every field except Id on the removed association so ReplaceAsync
cannot match the stored row by payload. Also stamp null-tenant batches
through SaveManyAsync on both label and association stores.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* test(labels): stamp null TenantId under a named ambient tenant
Cover SaveAsync and SaveManyAsync for labels and associations when
the ambient tenant is tenant-a, so a default-only stamp cannot pass.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* test(labels): reject tenant-A association leakage under tenant-B
Tenant-B FindByVersion and FindByLabelIds now require assoc-b and
assoc-star, and fail if assoc-a is visible.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>