-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add code blocks to the ch16 (get-authenticated-user) #29
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,60 +9,90 @@ create the products in `FeatureContext`. | |
I want to test that this table *does* show the correct author when its set. Create | ||
a new scenario to describe this: | ||
|
||
Scenario: Products show author | ||
Given I am logged in as an admin | ||
[[[ code('4c40dd7480') ]]] | ||
|
||
Instead of just saying there are five products I'll say: | ||
|
||
And I author 5 products | ||
[[[ code('5847ac3fba') ]]] | ||
|
||
This *is* new language that will need a step definition. To save time, we can go | ||
directly to the products page, | ||
directly to the products page: | ||
|
||
When I go to "/admin/products" | ||
Then I should not see "Anonymous" | ||
[[[ code('6edea384d7') ]]] | ||
|
||
Since "I" - some admin user - will be the author of the products, they should all | ||
show "admin": none will say "Anonymous". And we will *only* have these 5 products | ||
because we're clearing the database between each scenario to keep things independent. | ||
|
||
Run just this new scenario by using its line number. | ||
Run just this new scenario by using its line number: | ||
|
||
Great - copy the `iAuthorProducts` function code and paste it into our handy `FeatureContext` | ||
class - near the other product function. These two functions will be similar, so | ||
we should reuse the logic. Copy the internals of `thereAreProducts`, make a new | ||
`private function createProducts`. Pass it `$count` as an argument and also an optional | ||
User object which will be the author for those products. Now, add an if statement | ||
that says, if `$author` is passed then, `$product->setAuthor()`. I already have that | ||
relationship setup with in Doctrine. Great! | ||
```bash | ||
$ ./vendor/bin/behat features/web/product_admin.feature:13 | ||
``` | ||
|
||
In `thereAreProducts`, change the body of this function to `$this->createProducts($count);`. | ||
Do the same thing in `iAuthorProducts` for now. Clearly, this is still not setting | ||
the author. But I want to see if it executes first and then we'll worry about setting | ||
the author. | ||
Great - copy the `iAuthorProducts()` function code and paste it into our handy `FeatureContext` | ||
class - near the other product function: | ||
|
||
[[[ code('a2d4b5fdea') ]]] | ||
|
||
These two functions will be similar, so we should reuse the logic. Copy the internals | ||
of `thereAreProducts`, make a new `private function createProducts()`. Pass it `$count` | ||
as an argument and also an optional User object which will be the author for those products: | ||
|
||
[[[ code('8bbd967c08') ]]] | ||
|
||
Now, add an if statement that says, if `$author` is passed then, `$product->setAuthor()`: | ||
|
||
[[[ code('954b443f9e') ]]] | ||
|
||
I already have that relationship setup with in Doctrine. Great! | ||
|
||
In `thereAreProducts()`, change the body of this function to `$this->createProducts($count);`: | ||
|
||
[[[ code('95e36de658') ]]] | ||
|
||
Do the same thing in `iAuthorProducts()` for now: | ||
|
||
[[[ code('acd4d6cbd4') ]]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And the same question, should we wrap this single line with method name like: public function iAuthorProducts($count)
{
$this->createProducts($count);
} Looks like we get it from context above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I agree - we should give it more context. Sometimes, we're working in a function, and then we add a new line to it, then another new line later. In these cases, it seems less important to include the "context" on the 2nd and 3rd code-blocks (but still maybe not a bad thing). But when we switch to work on a different function - like we do here - then yea, definitely :). I'm in the code block editor right now, so I'll tweak these. |
||
|
||
Clearly, this is still not setting the author. But I want to see if it executes first | ||
and then we'll worry about setting the author. | ||
|
||
## Who is "I" in a Scenario? | ||
|
||
Cool! It runs... and fails because anonymous *is* still shown on the page. The question | ||
now is: how do we get the current user? The step says "I author". But who is "I" in this | ||
case? In `product_admin.feature`, you can see that "I" is whomever we logged in as. | ||
We didn't specify what the username should be for that user, but whoever is logged | ||
in is who "I" represents. | ||
case? In `product_admin.feature`: | ||
|
||
[[[ code('88c42ae944') ]]] | ||
|
||
You can see that "I" is whomever we logged in as. We didn't specify what the username | ||
should be for that user, but whoever is logged in is who "I" represents. | ||
|
||
When we worked with the `ls` scenarios earlier, we needed to share the command output | ||
string between the steps of a scenario. In this case, we have a similar need: we | ||
need to share the user object from the step where we log in, with the step where | ||
"I" author some products. To share data between steps, create a new `private $currentUser;`. | ||
"I" author some products. To share data between steps, create a new `private $currentUser;`: | ||
|
||
[[[ code('100d047bcd') ]]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @weaverryan Should we add more context here and wrap this property with class in the code block? I show a single line of property declaration here in code block now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
|
||
In `iAmLoggedInAsAnAdmin()`, add `$this->currentUser = $this->thereIsAnAdminUserWithPassword()`: | ||
|
||
[[[ code('9d15e806ff') ]]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I gave this more context too - it was just the single line, I expanded it to show the method name above (and the opening |
||
|
||
In `iAmLoggedInAsAdmin`, add `$this->currentUser = $this->thereIsAnAdminUserWithPassword()`. | ||
Click to open that function. It creates the `User` object of course, but now we need | ||
to also make sure it returns that. | ||
to also make sure it returns that: | ||
|
||
[[[ code('d7766a9278') ]]] | ||
|
||
And that's it! This login step will cause the `currentUser` property to be set and | ||
in `iAuthorProducts` we can access that and pass it into `createProducts()` so that | ||
each product us authored by us. It's pretty common to want to know *who* is logged | ||
in, so you'll likely want to use this in your project. | ||
in `iAuthorProducts()` we can access that and pass it into `createProducts()` so that | ||
each product us authored by us: | ||
|
||
[[[ code('15862f69e1') ]]] | ||
|
||
It's pretty common to want to know *who* is logged in, so you'll likely want to use | ||
this in your project. | ||
|
||
And hey it even passes! Now you can continue to write scenarios in terms of actions | ||
that "I" take and we will actually know who "I" is. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THANK you for adding commands when we run command - I also try to do this, but I don't catch them all. But (unlike the core Symfony docs) - we don't need to add a
$
- we add a>
via CSS when it renders :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry... I forgot about this CSS feature here.