Skip to content
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

Upgrade to Laravel 5.4 #227

Merged
merged 9 commits into from
Sep 22, 2017
Merged

Upgrade to Laravel 5.4 #227

merged 9 commits into from
Sep 22, 2017

Conversation

m1guelpf
Copy link
Contributor

@m1guelpf m1guelpf commented Jul 20, 2017

This pull request upgrades Symposium to Laravel 5.4

Copy link
Member

@mattstauffer mattstauffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this!

@@ -20,8 +20,8 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
\Blade::setRawTags('{{', '}}');
\Blade::setContentTags('{{{', '}}}');
// \Blade::setRawTags('{{', '}}');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to escape this, we need to make sure we change the output style everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

config/app.php Outdated
@@ -165,7 +165,7 @@
'Collective\Html\HtmlServiceProvider',
'Thomaswelton\LaravelGravatar\LaravelGravatarServiceProvider',
'Thujohn\Twitter\TwitterServiceProvider',
'Maknz\Slack\SlackServiceProvider',
M1guelpf\Slack\SlackServiceProvider::class,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other package is no longer supported, and is not Laravel5.4-compatible.

No talks yet.
</li>
@endforelse
@each('partials.talk-in-list', $talks, 'talk', 'partials.talk-in-list-empty')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many spaces indent

@@ -0,0 +1 @@
No talks yet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this need an

  • around it?

  • @@ -2,11 +2,11 @@

    use App\User;
    use Laracasts\TestDummy\Factory;
    use MailThief\Testing\InteractsWithMail;
    // use MailThief\Testing\InteractsWithMail;
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    If we don't need this we can delete it

    {
    public $userId;

    public function __construct()
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Is constructor necessary?

    @@ -5,12 +5,12 @@
    use Illuminate\Foundation\Testing\DatabaseMigrations;
    use Illuminate\Support\Facades\Session;
    use Laracasts\TestDummy\Factory;
    use MailThief\Testing\InteractsWithMail;
    // use MailThief\Testing\InteractsWithMail;
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    same as in previous; if we don't need it then you can delete it

    // $this->assertEquals(0, $conference->submissions->count());
    // $this->assertFalse($conference->submissions->contains($revision));
    // }
    // }
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ? This is not OK

    Copy link
    Contributor Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I temporally commented it out because it was failing for an unknown reason.


    namespace Tests\Api;

    class DummyAuthorizer extends Authorizer
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Why introduce a class that's never used?

    @@ -3,7 +3,7 @@
    namespace App\Handlers\Events;

    use Illuminate\Support\Facades\App;
    use Maknz\Slack\Facades\Slack;
    use Slack;
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Importing façades with their FQCN is an intentional decision.

    @@ -1,4 +1,5 @@
    <div class="pull-right">
    Copy link
    Contributor Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Fixed

    @m1guelpf
    Copy link
    Contributor Author

    @mattstauffer I think I need help with the failing/commented out tests. The feature works in my browser, but fails in the tests...

    @imjohnbon
    Copy link
    Contributor

    imjohnbon commented Aug 10, 2017

    @m1guelpf Hi Miguel, thank you for all of your work on this upgrade! I took some time this morning to review the failing/commented out tests that you noted and was able to get to the bottom of it. I wanted to take a moment to outline what the issues were, as they were definitely a bit obscure.

    The majority of the tests that were causing issues were in the tests/SubmissionTest.php file. I noticed that each test that was failing was failing because of a line like this:

    $this->assertTrue($conference->submissions->contains($revision));

    The error message was saying that it failed to "assert that false is true", meaning that the contains method on the collection was failing to find the model within the collection. This was especially confusing because when I dd()'d $conference->submissions in the terminal, I could see that the $revision clearly was inside the collection, which made it appear that the contains method itself was broken. That seemed hard to believe, but made sense when I dug deeper.

    When you call contains on an Eloquent collection, and you pass in a model, here's the code that eventually gets run (in Laravel 5.4):

    return parent::contains(function ($model) use ($key) {
        return $model->is($key);
    });
    

    You can see that on line 87 of Illuminate\Database\Eloquent\Collection.

    Alternatively, here's the code that gets run when you call contains on an Eloquent collection when you pass in a model in Laravel 5.3:

    return parent::contains(function ($model) use ($key) {
        return $model->getKey() == $key;
    });
    

    This one you can see on line 83 of Illuminate\Database\Eloquent\Collection.

    As you can tell, in 5.3 contains does a basic check for the models key (usually the id) within the collection. But in 5.4 it runs an is method on the model instead. Here's what that is method looks like:

    public function is(Model $model)
    {
        return $this->getKey() === $model->getKey() &&
            $this->getTable() === $model->getTable() &&
            $this->getConnectionName() === $model->getConnectionName();
    }
    

    The is method checks if a couple things are equal (the key, the table, and the connection name), and that's where the problem comes in. When you create a factory like this (like we do in every test):

    $revision = Factory::create('talkRevision');

    and then call getConnectionName on it like this:

    $revision->getConnectionName()

    You're going to see it returns null. In order to be able to successfully get the connection name from the model, we need to grab a fresh copy of it from the database like so:

    $revision = $revision->fresh();

    Now if you call getConnectionName on $revision you're going to see it returns something like testing (if it's being run during a test).

    So, that was the underlying issue here. We were passing an Eloquent model into the contains method right after it was created by a Factory, which was causing getConnectionName to return null and thus, fail the is check. Prior to 5.4, without the is check, this test passed just fine.


    The one other test that was failing was the user_can_reset_their_password_from_email_link test inside tests/AccountTest.php. The test was assuming that after we reset our password, we would be sent back to the dashboard page, however in actuality, we were being sent back to the reset password page. After dd()'ing the response in the terminal, I realized that the test was failing because the password reset token was invalid, thus triggering a validation error and taking us back to the password reset page.

    Anyway, here's the relevant portion of the code from that test:

    $reset_token = DB::table('password_resets')->where('email', $user->email)->pluck('token')->first();
            
    $this->visit('/password/reset/' . $reset_token)
    
    ...
    

    As you can see, we grab the reset token from the database, and then we pass that into the reset password URL for the test. However, after a bit of Googling, I found out that there was an undocumented change in how password reset tokens worked between 5.3 and 5.4. You can read more about it here, but essentially the tokens are now hashed before they are stored in the database. However, the un-hashed version is still what goes in the URL in the email that gets sent to the user.

    So, essentially, we were trying to use the hashed version of the token in the URL (because we got it from the database directly), when what we really needed was the un-hashed version. This led me down a bit of a rabbit hole of trying to figure out how to get that un-hashed version (since it's not stored anywhere in the DB). Luckily, I eventually found this Stackoverflow that held the answer. By using a Notification fake in the test, we can get the un-hashed version via a callback, and use it successfully in our test.


    If you have any questions about any of this, I'd be happy to answer. Thanks again for all the hard work!

    @m1guelpf
    Copy link
    Contributor Author

    @imjohnbon So this is ready now?

    @mattstauffer
    Copy link
    Member

    @imjohnbon thanks for your hard work sussing that out!

    @m1guelpf nope, not ready. John is going to move the Slack notifications over to native Laravel notifications and then I'll review the whole thing again.

    @imjohnbon
    Copy link
    Contributor

    @mattstauffer Thanks! The Slack notifications have now been fully converted over to native Laravel notifications.

    @m1guelpf
    Copy link
    Contributor Author

    m1guelpf commented Sep 6, 2017

    @mattstauffer ping

    @mattstauffer
    Copy link
    Member

    Upgrading Vue and Axios etc. broke the Vue content. Currently deciding whether to upgrade it or just downgrade the dependencies.

    @mattstauffer mattstauffer merged commit 494cb32 into tighten:master Sep 22, 2017
    @mattstauffer
    Copy link
    Member

    Ugh. Also this requires 7.1 and symposium is currently hosted on 7.0.

    @m1guelpf
    Copy link
    Contributor Author

    @mattstauffer Would you accept another PR for 5.5?

    @mattstauffer
    Copy link
    Member

    @m1guelpf Sure! I'll try to get this on a 7.1 server soon. Thanks!

    @mattstauffer
    Copy link
    Member

    @m1guelpf it's now on a 7.1 server, so you're welcome to PR 5.5 if you'd like. Thanks!

    @m1guelpf
    Copy link
    Contributor Author

    m1guelpf commented Oct 6, 2017

    @mattstauffer I've submitted lucadegasperi/oauth2-server-laravel#777, but the project is no longer mantained, so I guess the first thing to do would be switching to Passport.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    None yet
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    3 participants