Commit 2abb1b06 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add further tests for various types of page

parent 2589fe2b
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
Feature: Homepage
	The homepage should display either a static page or a feed
Feature: Pages
	Pages should be returned when their URL is requested.

	Scenario: static homepage
	Background: A page exists
		Given a page exists containing
			"""
			This is some page content
			"""
		And the page is configured as the homepage
		When the homepage is requested

	Scenario: A page type post
		When the page is requested
		Then OK is returned
		And we will see the page text

	Scenario: feed homepage
		Given a post exists containing
			"""
			This is some post content
			"""
		And the homepage is the default
	Scenario: Static homepage
		Given the page is configured as the homepage
		When the homepage is requested
		Then OK is returned
		And we will see the post text
		And we will see the page text

tests/posts.feature

0 → 100644
+25 −0
Original line number Diff line number Diff line
Feature: Posts
	Posts should be returned when their URL is requested.  The post index page
	should also be accessible.

	Background: A post exists
		Given a post exists containing
			"""
			This is some page content
			"""

	Scenario: Individual posts
		When the post is requested
		Then OK is returned
		And we will see the post text

	Scenario: Homepage post index
		When the homepage is requested
		Then OK is returned
		And we will see the post text

	Scenario: Non-homepage post index
		Given a blank page exists
		And is configured as the post index
		When the page is requested
		Then we will see the post text
+54 −0
Original line number Diff line number Diff line
Feature: Script Access and Restrictions
	The user-facing parts of a WordPress application should all be either static
	resources or channeled through the root *index.php* entrypoint.  However PHP
	is architectured in such a way that, if left unrestricted, any PHP file
	could be accessed as a script.

	In many cases protections have been put in place in WordPress' PHP files to
	prevent circumvention of access restriction, as well as some plugins.
	However this should never be relied on as it introduces additional
	complexity and may not have been thoroughly tested.  It could also be
	considered a UI bug if a non-404 code is returned.

	To confuse matters the administration interface *is* accessed in a
	one-script-per-endpoint manner.

	Scenario Outline: Direct file access
		When <path> is requested
		Then <result> is returned

		Examples: Static files
			| path                                                | result    |
			| /wp-includes/images/w-logo-blue.png                 | OK        |
			| /wp-admin/images/w-logo-blue.png                    | OK        |
			| /readme.html                                        | Not Found |
			| /composer.json                                      | Not Found |
			| /composer.lock                                      | Not Found |

		Examples: Non-entrypoint PHP files
			| path                                                | result    |
			| /wp-activate.php                                    | Not Found |
			| /wp-blog-header.php                                 | Not Found |
			| /wp-comments-post.php                               | Not Found |
			| /wp-config.php                                      | Not Found |
			| /wp-cron.php                                        | Not Found |
			| /wp-load.php                                        | Not Found |
			| /wp-mail.php                                        | Not Found |
			| /wp-settings.php                                    | Not Found |
			| /wp-signup.php                                      | Not Found |
			| /wp-trackback.php                                   | Not Found |
			| /xmlrpc.php                                         | Not Found |
			| /wp-includes/user.php                               | Not Found |

		Examples: Entrypoint PHP files
			| path                                                | result    |
			| /                                                   | OK        |
			| /index.php                                          | 301       |
			| /wp-login.php                                       | OK        |
			| /wp-admin/                                          | 302       |
			| /wp-admin/index.php                                 | 302       |

	Scenario: Check the JSON API is accessible
		When /wp-json/wp/v2/ is requested
		Then OK is returned
		And the response body is JSON
+43 −12
Original line number Diff line number Diff line
@@ -58,12 +58,13 @@ def assert_not_exist(context: Context, path: str) -> None:
		f"{context.site.url / path} exists"


@given("a blank {post_type:PostType} exists")
@given("a {post_type:PostType} exists containing")
def create_post(context: Context, post_type: PostType, text: str|None = None) -> None:
	"""
	Create a WP post of the given type and store it in the context with the type as the name
	"""
	post = use_fixture(wp_post, context, post_type, text or context.text)
	post = use_fixture(wp_post, context, post_type, text or getattr(context, "text", ""))
	setattr(context, post_type.value, post)


@@ -72,21 +73,15 @@ def set_homepage(context: Context) -> None:
	"""
	Set the WP page from the context as the configured front page
	"""
	wp = context.site.backend
	pageid = context.page.path("$.ID", int)
	wp.cli("option", "update", "page_on_front", str(pageid))
	wp.cli("option", "update", "show_on_front", "page")

	page = use_fixture(wp_post, context, PostType.page)
	wp.cli("option", "update", "page_for_posts", page.path("$.ID", int, str))
	use_fixture(set_specials, context, homepage=context.page)


@given("the homepage is the default")
def reset_homepage(context: Context) -> None:
@given("is configured as the post index")
def set_post_index(context: Context) -> None:
	"""
	Ensure the front page is reverted to it's default
	Set the WP page from the context as the post index page
	"""
	context.site.backend.cli("option", "update", "show_on_front", "post")
	use_fixture(set_specials, context, posts=context.page)


@when("the {post_type:PostType} is requested")
@@ -160,3 +155,39 @@ def wp_post(
	)
	yield post
	wp.cli("post", "delete", postid)


@fixture
def set_specials(
	context: Context, /,
	homepage: JSONObject|None = None,
	posts: JSONObject|None = None,
	*a: Any,
	**k: Any,
) -> Iterator[None]:
	"""
	Set the homepage and post index to new pages, creating default pages if needed

	Pages are reset at the end of a scenario
	"""
	wp = context.site.backend

	options = {
		opt["option_name"]: opt["option_value"]
		for opt in wp.cli("option", "list", "--format=json", deserialiser=JSONArray.from_string)
	}

	homepage = homepage or use_fixture(wp_post, context, PostType.page)
	wp.cli("option", "update", "page_on_front", homepage.path("$.ID", int, str))
	wp.cli("option", "update", "show_on_front", "page")

	posts = posts or use_fixture(wp_post, context, PostType.page)
	wp.cli("option", "update", "page_for_posts", posts.path("$.ID", int, str))

	yield

	for name in ["page_on_front", "show_on_front", "page_for_posts"]:
		try:
			wp.cli("option", "update", name, options[name])
		except KeyError:
			wp.cli("option", "delete", name)
+12 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ Step implementations dealing with HTTP requests

from __future__ import annotations

import json
from typing import Any

from behave import then
@@ -84,3 +85,14 @@ def assert_response(context: Context, response: ResponseCode) -> None:
	"""
	assert context.response.status_code == response, \
		f"Expected response {response}: got {context.response.status_code}"


@then("the response body is JSON")
def assert_is_json(context: Context) -> None:
	"""
	Assert the response body of a previous step contains a JSON document
	"""
	try:
		context.response.json()
	except json.JSONDecodeError:
		raise AssertionError("Response is not a JSON document")
Loading