PHPUnit: Integration Testing with Live Services
… When do I need that?
Accessing services from the container
Clearing the database between tests
Seeding the database
Foundry Factories & more!
Partial Mocking: mock just some dependencies
Testing emails
Testing messenger messages
Integration tests are fun and are a critical tool to a well-rounded…
Allow Admin Users to Edit any Treasure
…a public function testAdminCanPatchToEditTreasure().
Then create an admin user with UserFactory::createOne() passing roles set to
ROLE_ADMIN:
That'll work fine. But if we need to create a lot of admin users in our tests,
we can add a shortcut to Foundry. Open UserFactory…
State Processors: Hashing the User Password
…Now, we need to hash that password before the User
is saved to the database. Like we showed when working with Foundry, hashing a
password is simple: grab the UserPasswordHasherInterface service then call a
method on it:
But to pull this off, we need a…
API Platform 3 Part 2: Security for your Treasures
…imaginable... and spin up a nifty test suite along the way:
Disabling documentation on production
Different types of API authentication
Logging in via Ajax & sessions
Creating an API Token system with "scopes"
Securing your API resources
Bootstrapping tests with zenstruck/browser & zenstruck/foundry!
How to…
Custom Resource State Processor
…tests/Functional/, create a new class
called DailyQuestResourceTest. Make this extend the ApiTestCase that we created
in the last tutorial and use ResetDatabase from Foundry to make sure our database
is empty at the start of every test. Also use Factories.
Ok, we don't…
Doctrine, Symfony 6 & the Database
…with Docker via the Flex recipe system
Database config
Creating (and updating) Entities with make:entity
Generating & using migrations
Inserting new data
Fetching & Querying for data
Doctrine Repositories
Custom queries and the query builder
Fixtures (Dummy data) using Foundry
Relationships & Associations
SELECT * FROM doctrine_knowledge.
QuestionTag Fixtures & DateTimeImmutable with Faker
…reflect
this.
First, since we now have a QuestionTag entity, we are going to be creating
and persisting QuestionTag objects directly. So let's generate a Foundry factory
for it. At your terminal, run:
symfony console make:factory
And choose QuestionTag. Go open that up…
Saving Relations
… This is actually
pretty easy... but it might feel weird if you're used to working with databases
directly.
Open up src/DataFixtures/AppFixtures.php. We're using Foundry to add rich fixtures,
or fake data, into our project.
But to see how relationships work…
Detecting the "Published" State Change
…send the
PUT request, there is exactly one CheeseNotification in the database. Now,
thanks to Foundry - the library that helps us insert dummy data both in
our data fixtures and in our tests - before each test case, our database is
emptied. That will make it…
Symfony 5: Mastering Doctrine Relations
…Generating a ManyToOne relationship (association)
Relation annotations / PHP 8 attributes
The OneToMany inverse side of a relation
Handling relationships in fixtures with Foundry
The owning versus inverse sides of a relation
Doing magic with the ArrayCollection (Criteria)
Querying with Joins
ManyToMany Relations
So let's…
Doctrine, Symfony & the Database
…s go!
Booting a database with Docker via make:docker:database
Database Configuration
Creating (and updating) Entities with make:entity
Generating & using migrations
Inserting new data
Fetching & Querying for data
Doctrine Repositories
Custom queries and the query builder
Fixtures (Dummy data) using Foundry
Relationships & Associations
Symfony End-to-End Testing: WebTestCase to Playwright
…and Symfony's built-in functional testing tools
zenstruck/browser for expressive, fluent browser tests
Creating exactly the database state we need with zenstruck/foundry
Keeping database tests isolated and fast with DAMA DoctrineTestBundle
Running the test suite in parallel with ParaTest
Testing forms, authentication…
Disabling Users with a Custom UserChecker
…enabled or disabled,
public function isEnabled(): bool and inside, return null === $this->disabledAt;:
Foundry gives you the ability to add states to your factory, and it's pretty simple
to do. I want to add a disabled state to our user factory so we…
User Doctrine Relationship
…Finally,
'status' => StarshipStatusEnum::IN_PROGRESS:
Great! Back in the terminal, reload the fixtures with:
symfony console foundry:load-fixtures
Now to grab "my ship" from the currently logged-in user! Back in MainController::index(),
set $myShip to $this->getUser()?->getStarship():
The getUser() method is…
Customizing Authentication Error Messages
…makeitso. "Account is disabled."
We see the real error now.
Reload the fixtures so Picard is enabled again:
symfony console foundry:load-fixtures
Now use a wrong password: enterprise. "Invalid credentials."
That makes sense - the credentials were invalid.
But try an email that doesn't…
Accessing Data on a ManyToMany
…separated string.
Now that we've got a getDroidNames() method, we can say
{{ ship.droidNames ?: 'none' }}.
We're done! Refresh... and enjoy the droid names on the homepage.
Next: let's use Foundry to set the ManyToMany relationship in the fixtures.
Another place Foundry shines!
Many To One: The King of Relationships
…we see a handy getParts() method.
But instead of setParts(), we've been gifted addPart() and
removePart() methods:
These will come in handy when you work with Foundry, the form system or if you're
building an API with Symfony's serializer.
In the constructor…
Part Entity
…we need a migration!
symfony console make:migration
Then migrate:
symfony console doctrine:migrations:migrate
In the last tutorial, we used a cool library called Foundry to quickly
create a bunch of dummy data. We're going to do the same for
StarshipPart. Step 1 …
The Two Sides of a Relation: Owning vs Inverse
…Our favorite error pops up
starship_id cannot be null
Totally expected.
To demonstrate the owning vs inverse issue, add _real() to the end of $starship:
When you create an entity via foundry, it actually wraps it in a little gift
called a proxy object…
Cascade Persist
…again:
Guess what? They work!
Behind the scenes, Foundry is calling addDroid() on each Starship for
each droid. And we just proved that addDroid() is back in action.
The creation of the StarshipDroid join entity is now hidden
from our entire codebase!
But, what if…
x
196