Archived
Admin - /api/admin: products CRUD, the enquiry inbox, and presigned photo upload straight to the bucket so images never pass through the app. Gated by platform.security.authenticated-paths = /api/admin/**, so any signed-in Authentik user is staff — the alternative is a role model a two-person bakery would never maintain. - /api/me is deliberately PUBLIC. The SPA asks on every page load, and requiring a login would bounce every anonymous visitor to Authentik just to read the menu. - /admin screens: product list with edit and remove, an editor with drag-free photo reordering and upload, and an enquiry inbox that flags anything the relay refused. Gallery - swipe on touch devices, which the react-awesome-slider it replaced had and this did not, plus arrow keys and position dots — with swipe there is otherwise nothing to say a card holds more than one photo. Vertical drags are ignored so page scrolling still works. - @BatchSize on the photo collection: the products page loaded the whole catalogue and Hibernate issued a query per product for its images, forty-odd round trips for a page that needs two. Three things the tests caught, none of which are obvious: - Adding the storage starter broke every existing test. It activates on a default endpoint, so an S3 client is built even in tests and dies on blank keys. - MockMvc's webAppContextSetup leaves the security filter chain OUT, so the first version of the security test passed 200s and proved the opposite of what it claimed. It needs .apply(springSecurity()). - Turning on the security starter turns on CSRF — for the PUBLIC contact form too, which then 403s. The SPA now reads the XSRF-TOKEN cookie and sends X-XSRF-TOKEN, and there is a test asserting the form is rejected without it.
29 lines
1.1 KiB
Java
29 lines
1.1 KiB
Java
package com.itsthevine.web;
|
|
|
|
import org.springframework.boot.test.context.SpringBootTest;
|
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
|
import org.testcontainers.containers.PostgreSQLContainer;
|
|
import org.testcontainers.junit.jupiter.Container;
|
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
|
import org.testcontainers.utility.DockerImageName;
|
|
|
|
import net.thebennett.platform.test.PlatformWebContract;
|
|
|
|
/** Everything in {@link PlatformWebContract} — what this app must do because it is on the platform. */
|
|
@SpringBootTest(properties = {
|
|
// The storage starter activates on its default endpoint, so an S3 client is built even in
|
|
// tests and fails on blank keys.
|
|
"platform.storage.access-key=test",
|
|
"platform.storage.secret-key=test",
|
|
"[email protected]",
|
|
"[email protected]"
|
|
})
|
|
@Testcontainers
|
|
class PlatformContractTest extends PlatformWebContract {
|
|
|
|
@Container
|
|
@ServiceConnection
|
|
static PostgreSQLContainer<?> postgres =
|
|
new PostgreSQLContainer<>(DockerImageName.parse("postgres:18-alpine"));
|
|
}
|