odatadol.testing#

A scripted OData service for tests: no network, no password.

FakeService is a fetch ((url, headers) -> (status, bytes)) that answers like a real, quirky server did: it refuses Accept: text/plain on $count, 404s a URL past max_url the way an IIS front end does, writes raw CR characters inside JSON strings, and takes double-quoted names in $select/$orderby. It records every URL it was asked for, so a test can assert what crossed the wire.

>>> server = FakeService([{'ProductID': 1, 'Unit Price': 2.5}])
>>> from odatadol import entity_records
>>> list(entity_records('https://example.com/odata', 'Products', fetch=server,
...                     select=['ProductID', 'Unit Price']))
[{'ProductID': 1, 'Unit Price': 2.5}]
>>> sorted(server.asked_for())
['ProductID', 'Unit Price']

Its $filter understands what odatadol itself sends: comparisons (eq ne gt ge lt le) of a property with a literal, joined by and.

Functions

csdl(entity, properties, *[, namespace, ...])

A minimal CSDL $metadata document declaring one entity set.

Classes

FakeService(rows, *[, entity, metadata, ...])

Answers OData requests over rows like a quirky real server, and records them.

class odatadol.testing.FakeService(rows, *, entity='Entities', metadata=None, max_url=10000, page_cap=None, next_links=False, require_auth=False)[source]#

Bases: object

Answers OData requests over rows like a quirky real server, and records them.

Parameters:
  • rows (Iterable[Mapping[str, Any]]) – The records of every entity set it serves (one set is enough for tests).

  • entity (str) – The entity set the default $metadata declares.

  • metadata (bytes | None) – The $metadata body; defaults to one declaring entity with an Edm.String for every property of the first row.

  • max_url (int) – URLs longer than this get an IIS-style 404.

  • page_cap (int | None) – Serve at most this many records per page, whatever $top asks, and say nothing about it (unless next_links), as some servers do.

  • next_links (bool) – Page by @odata.nextLink (with a $skiptoken) when a page is capped, as server-driven paging does.

  • require_auth (bool) – Answer 401 to a request without an Authorization header.

asked_for()[source]#

Every property named in a $select it was sent.

Return type:

set[str]

odatadol.testing.csdl(entity, properties, *, namespace='Demo', type_name=None, annotations=None, nullable=None)[source]#

A minimal CSDL $metadata document declaring one entity set.

Parameters:
Return type:

bytes