tests.test_cloudflare module

Tests for the Cloudflare Pages drift reconciliation.

Everything runs against a mocked _call: the module’s value is the diffing, merging and credential-resolution logic, none of which needs a live account to prove.

tests.test_cloudflare.credentials(monkeypatch)[source]

Environment credentials, so no code path goes looking for wrangler’s.

tests.test_cloudflare.SOLO_ACCOUNT = [{'id': 'account-under-test', 'name': 'Test'}]

What /accounts answers in the stand-ins: one account, so the credential resolves its target without any project probing.

tests.test_cloudflare.test_desired_settings_manage_only_what_is_declared()[source]

An empty declaration leaves the live value alone, floors excepted.

tests.test_cloudflare.test_desired_settings_apply_declarations_to_both_environments()[source]

Pages has exactly production and preview, and both get every value.

tests.test_cloudflare.test_diff_reads_a_missing_key_as_the_null_it_wants()[source]

Cloudflare reports “unset” as null or as absence, and both must match.

Without the equivalence, whichever form the API is not currently using reads as drift, and --apply would PATCH a no-op forever.

tests.test_cloudflare.test_diff_accepts_a_freshly_created_project_as_clean()[source]

A project created seconds ago carries no build_config object at all.

That absence is the strongest possible statement that nothing builds it, so it must not read as drift against the empty string saying the same. Reported as drift, --create closed by declaring a fault in the project it had just made correctly, and pointed at a dashboard field that does not exist yet.

tests.test_cloudflare.test_diff_treats_every_spelling_of_unset_alike(live)[source]

Which form arrives depends on the field and the project’s age.

tests.test_cloudflare.test_diff_still_catches_a_real_build_command()[source]

The equivalence must not swallow a project someone reconnected.

tests.test_cloudflare.test_diff_reports_live_value_next_to_wanted_one()[source]
tests.test_cloudflare.test_nest_and_merge_build_one_patch_body()[source]
tests.test_cloudflare.test_redact_scrubs_every_secret_key()[source]
tests.test_cloudflare.test_token_prefers_the_environment(monkeypatch)[source]
tests.test_cloudflare.test_token_falls_back_to_wrangler_login(monkeypatch, tmp_path)[source]
tests.test_cloudflare.test_token_refuses_an_expired_wrangler_session(monkeypatch, tmp_path)[source]

A stale local login must name itself, not 403 somewhere downstream.

wrangler refreshes its own token transparently and nothing here does, so a session left overnight hands Cloudflare a dead credential. Left to the API, that arrives as a bare 403 on whichever call runs first, which reads as a scope problem and sends the reader auditing permissions that were never wrong.

tests.test_cloudflare.test_token_accepts_a_live_wrangler_session(monkeypatch, tmp_path)[source]
tests.test_cloudflare.test_token_tolerates_a_session_with_no_recorded_expiry(monkeypatch, tmp_path)[source]

An unreadable or absent expiry must not block a working credential.

tests.test_cloudflare.test_token_absence_names_both_remedies(monkeypatch, tmp_path)[source]
tests.test_cloudflare.test_account_resolves_a_lone_account_from_the_token()[source]

The ordinary case: one account, so nothing needs configuring.

A token scoped to nothing but Cloudflare Pages: Edit still enumerates the account it belongs to, which is what lets CI carry the token alone.

tests.test_cloudflare.test_account_picks_the_one_owner_among_several_accounts()[source]

A multi-account credential resolves by project ownership.

The project name is always known to the caller, so asking which account holds it settles what an identifier used to be stored for.

tests.test_cloudflare.test_account_lookup_skips_no_probing_for_a_lone_account()[source]

The common path costs one call: no project probing when unneeded.

tests.test_cloudflare.test_account_refuses_when_no_account_is_visible()[source]

An empty answer points at a token made under the wrong account.

tests.test_cloudflare.test_account_refuses_to_guess_among_several_accounts(owners, fragment)[source]

Ownership that has no single answer fails loudly rather than guessing.

Deploying into a guessed account is worse than not deploying, and the remedy for both shapes is the same: a token created under the account the project belongs to.

tests.test_cloudflare.test_check_clean_project_exits_zero(credentials, capsys)[source]
tests.test_cloudflare.test_check_drifted_project_exits_one_and_explains(credentials, capsys)[source]
tests.test_cloudflare.test_check_flags_a_reattached_git_source_as_read_only(credentials, capsys)[source]

The one drift --apply must not touch: a source block means a second publisher, and unpicking that belongs in the dashboard, deliberately.

tests.test_cloudflare.test_apply_patches_only_the_managed_drift(credentials, capsys)[source]
tests.test_cloudflare.test_attach_domain_registers_the_hostname_and_its_dns(credentials, capsys)[source]

The two halves the dashboard does together and the API does not.

tests.test_cloudflare.test_attach_domain_is_idempotent(credentials, capsys)[source]

Re-running after fixing one half must not disturb the other.

tests.test_cloudflare.test_attach_domain_reports_dns_it_cannot_write(credentials, capsys)[source]

A Pages-only token attaches the hostname and cannot finish the job.

Exits non-zero: a domain resolving to nothing never leaves pending, so reporting success would describe a site that does not load.

tests.test_cloudflare.test_attach_domain_finds_the_zone_above_a_subdomain(credentials, capsys)[source]

docs.example.com lives in example.com, so labels get stripped.

tests.test_cloudflare.test_attach_domain_survives_a_credential_that_cannot_read_zones(credentials, capsys)[source]

A deploy token scoped to Pages alone carries no Zone → Read.

tests.test_cloudflare.test_dump_redacts_and_exits_zero(credentials, capsys)[source]
tests.test_cloudflare.test_create_posts_the_project_when_missing(credentials, capsys)[source]
tests.test_cloudflare.test_create_reuses_an_existing_project(credentials, capsys)[source]

The API answers 409 on a duplicate name, so a re-run must converge.

Probing first turns an existing project into the same reconcile path a fresh one takes, instead of an error.

tests.test_cloudflare.test_create_still_fails_on_a_non_404_refusal(credentials, capsys)[source]

A 403 is not ‘missing’: it must surface, not trigger a POST.

tests.test_cloudflare.test_token_expiry_warning_counts_down(days_away, warns)[source]

Cloudflare never warns about expiry, so the drift check has to.

tests.test_cloudflare.test_token_expiry_warning_counts_the_hours_of_a_last_day()[source]

A token dying today is hours away: whole days would floor that to zero.

tests.test_cloudflare.test_token_expiry_warning_never_fails_the_run()[source]

A credential that verifies nowhere still deploys fine: silence, not error.