Testing React withRouter

One area I’ve always found tricky when writing tests for React is where Higher Order Components are involved. I’ve found this complicates the test setup process. There are ways around this, which may or may not be possible depending on many factors. Sometimes you work on third party code that won’t accept ‘dramatic’ refactors just to scratch your own testing itches.

One example of where this problem might occur (particularly if you don’t read the docs!!) is with React Router, specifically when using withRouter.

In this example I have MyComponent which wants to history.push('/some/location') when the user completes some action.

I’d like to test that this process takes place as expected.

Here was my first attempt. This way works, but there are some drawbacks:

This works.

There are a couple of drawbacks to this:

  • It involves a couple of extra imports.
  • Behind the scenes, withRouter is still used (afaik) but by wrapping in another Router, we can override the history prop.

As this particular approach is so common, React Router gives us an alternative / preferable way to test this workflowWrappedComponent.

The necessary actions to ‘run’ this test are unchanged. However, there are fewer lines as we can make use of the existing constructs provided by React Router to aid our testing workflow.

This may have been extremely obvious to you.

I can’t remember if WrappedComponent has always been available and I have overlooked it, or it is something new since I last had to do testing with a project using React Router.

Either way, it’s time I refreshed my knowledge of the documentation. And hopefully this helps someone else when testing withRouter at some point in the future.

[ReactJS] I Still Find Too Many People Who Don’t Know This Cool Tip

If you have:

You don’t need the

You can just use:

And get the same outcome.

It reads a lot nicer.

How I Fixed: UglifyJs Unexpected token: name (DropIn)

I’ve been trying – in vain – to build the front end for CodeReviewVideos. The issue I have been hitting upon is as follows:

uglifyjs-unexpected-token-name-dropin

As the error states, the issue is with the UglifyJs plugin, which I use in combination with WebPack.

This is a frustrating show-stopping problem. Unless fixed, I couldn’t complete a build.

Here’s what I had in my WebPack prod config:

This was only in my WebPack prod config. Therefore I didn’t notice any issue until trying to build for prod.

Now, in truth, I didn’t write the code / config above. I copy / pasted from somewhere else (I forget where) and as it just worked I didn’t pay much attention to it.

When it stopped working, I got sad, then got on to trying to fix it.

My Solution

There’s a bunch of suggested general solutions to this problem. A quick Google will turn up plenty of GitHub issues. Unfortunately none of them were specific to my exact error.

In my case, as best I understand it, the Braintree Web Drop In React should have compiled the dist.js file down to ES5, but is instead, in ES6. I concluded this based on this and this.

dammit-jim-im-a-coder-not-a-webpack-genius
Dammit Jim, I’m a coder not a WebPack genius

Of course, I may be wrong.

Fixing this wasn’t that hard. I just needed to read the docs.

For me, this added:

To my devDependencies in package.json.

After which I updated my prod.js WebPack config as follows:

I’ve removed everything unrelated to this specific problem.

After which I could get my build to work.

The 2018 Beginners Guide to Back End (JSON API) + Front End Development

It’s been a few weeks in the making, but I am happy now to reveal my latest course here on CodeReviewVideos:

The 2018 Beginners Guide to Back End (JSON API) + Front End Development.

This course will cover building a JSON-based API with the following back-end stacks:

  1. ‘raw’ Symfony 4 (PHP)
  2. Symfony 4 with FOSRESTBundle (PHP)
  3. API Platform (PHP)
  4. Koa JS (JavaScript / node)

Behat will be used to test all of these APIs. One Behat project, four different API implementations – in two different languages (PHP and JS).

We’re going to be covering the happy paths of GET , POST , PUT , (optionally) PATCH , and DELETE.

We’ll also be covering the unhappy paths. Error handling and display is just as important.

Where possible we’re going to try and use just one Behat feature file. It’s not always possible – the various implementations don’t always want to behave identically.

There’s a ton of good stuff covered in these videos. But the back end is only half the battle.

Whether you want to “catch them all”, or you’re working with a dedicated front-end dev, it’s definitely useful to know the basics of both.

With that in mind, you can pick and choose whether to implement the back-end, or front-end, or both.

If you don’t want to implement a back-end yourself, cloning any of the projects and getting an environment up and running is made as easy as possible by way of Docker. But you don’t need to use Docker. You can bring-your-own database, and do it that way, too.

The Front End

Whatever back end you decide to spin up, the front end should play nicely.

We’re going to implement a few different front-ends. The two I’m revealing today are:

  1. ‘raw’ JavaScript
  2. React

I have plans for a few others, but each implementation is a fair amount of work and I don’t want to over promise at this stage. There’s definitely at least two more coming, but let me first get these two on the site 🙂

The raw JavaScript approach aims to show how things were in the ‘bad old days‘. The days before your package manager  would take up ~7gb of your hard disk with its cache  directory.

The benefit of working this way is that there’s really no extra ‘stuff’ to get in the way. We can focus on making requests, and working with responses.

But that said, this is 2018 and the many modern JavaScript libraries and frameworks are fairly awesome. You’ll definitely get a renewed sense of appreciation for how much easier your life is once you’re comfortable using a library like React, after having done things the hard way.

Again, as mentioned we will cover more than just raw JS and React. Currently each implementation is between ten and fifteen videos. Each video takes a couple of hours to write up, and another couple of hours to record on average. I’m going as fast as I can, and will upload and publish as quickly as possible.

You can watch them as they drop right here.

Site Update

Behind the scenes over the past 10 weeks I have been working on integrating CodeReviewVideos with Braintree.

This is to enable support for PayPal.

I tried to create a ticket for everything I could think of ahead of starting development.

And I added a new ticket for any issue I hit during development. I’m not convinced I tracked absolutely everything, but even so I completely underestimated just how much work would be involved in this feature.

Being completely honest, I have never been more envious of Laravel’s Spark offering. For $99 they get Stripe and Braintree integration, and a whole bunch more. Staggering.

There’s a bunch of other new and interesting features in this release.

I’ve taken the opportunity to migrate from Symfony 3 to Symfony 4 for the API. There’s a bunch of new issues that arose during this transition – I hadn’t given it much prior thought, but with the new front controller ( public/index.php) totally broke my Behat ( app_acceptance.php) setup.

This work is also enabling the next major feature which I will start work on, once PayPal is live. More on that in my next update.

I appreciate that from the outside looking in, there doesn’t seem to have been a great deal of activity on the site over the last few weeks. I can assure you that behind the scenes, there has never been more activity.

Have A Great Weekend

Ok, that’s about it from me for the moment.

As ever, have a great weekend, and happy coding.

p. s. – I would be extremely grateful if you could help me spread the word by clicking here to tweet about the new course.

Software Development Is Not Beginner Friendly

As we are coming to the end of the first part of the Wallpaper Website tutorial series, I wanted to quickly reflect on a bit of feedback I’ve had regarding these videos.

The gist of this feedback was that I had miss-sold the course as being “beginner friendly”, when in fact, it has been quite a tricky course.

Here’s my view point, and as ever, feel free to disagree:

Software Development is hard.

There are two approaches I could take:

  1. Show you abstract examples where I cover concepts on an individual basis.
  2. Show you a complete, working example and all the things that getting to a “working” state entail.

My life would be easier if I opted for #1.

However, in my opinion, I would be misleading you if that’s all I showed you.

I’ve been writing software for over 15 years now, and I still regularly underestimate just how much effort is required to go from the idea phase through to “phew, it’s finally online” phase.

And as I’m sure you know, even once it’s online (or launched), it’s not done. Far from it. If anything, that’s where the real work actually begins.

Working in software development in 2017 is hard. There are a ton of things to cover. This series has been about the more traditional approach – using Symfony (or PHP) for everything, front end and back end.

In reality, and as we push further into the second and third parts of this series, to become the most employable and to stand out from being “just another dev” you will need to know more than just Symfony (or PHP). You almost inevitably will need to be decent at JavaScript, too.

Does this make the series harder? Yes, unfortunately.

Is this still stuff a beginner needs to know? In my opinion, yes.

There’s no point in just showing you what I consider the old school approach. At least, not unless all you ever want to do is build old school style websites.

My guess is that you want to make websites – or web-based applications – like those that you typically interact with in 2017.

Can PHP – and more specifically, Symfony – get you to this point?

Yes. But only half of the way there.

The other half needs to be done in JavaScript.

In other words, Symfony for your back end, and JavaScript for the front end.

Which brings me back to the original bit of feedback that this course is not beginner friendly.

I would argue that the industry is no longer beginner friendly.

There is an immense learning curve to simply getting started.

Fortunately, once you are over the initial hump, things do get a bit easier.

This isn’t a problem unique to software development. Many industries expect you to have a very broad and general level of knowledge before specialising in a particular area.

That’s my opinion on the subject. As ever, please do feel free to hit reply and let me know yours. I’m not saying I’m always right by any means, and I am not averse to having my view points challenged 🙂

Follow Up From Last Week

Last week I posed a couple of questions in my “Would you use Symfony for SaaS?” post:

  1. How many other developers are using Symfony for SaaS, or SaaS-like services?
  2. Is Stripe / payment integration something that many other devs want or need tutorial content on?

Firstly, thank you to everyone who replied. I really appreciate you taking the time to respond.

I have learned that the majority of you are not using Symfony to build your own SaaS, or SaaS-like service.

This is useful to me as it helps shape the content I aim to produce.

Even though most of you are not doing SaaS related stuff, the payment integration video idea does seem popular.

As such, I have added a payment integration course to the ToDo list. This will cover not just Stripe but also Braintree (aka PayPal), and all the fun that supporting multiple providers entails.

Video Update

This week saw three new videos added to the site.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/adding-an-image-preview-on-edit

As mentioned earlier in this series, there is a way to integrate with VichUploaderBundle when working with EasyAdminBundle.

In doing so, one of the nice ‘bonus’ features is the image preview when viewing an existing entity with an attached image file.

In this video we look at a way to recreate this in our own implementation. It’s easier than you might think, and gives us a good opportunity to explore some of the less frequently used parts of Symfony’s form component.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/delete-should-remove-the-wallpaper-image-file

One problem that’s been bothering me throughout this series is that when recording the videos I will do some uploading of images, and then delete the Wallpaper entity, but the image file I uploaded still remains on disk.

To fix this we can copy a process we’ve covered for both Create and Update – which is to say we can listen for a different Doctrine event, that of preRemove.

As we might be changing over to use a different storage mechanism in the longer term (think: Amazon S3, not storing everything on the server’s local hard disk), we also need to abstract away exactly how an image file is deleted.

We will no doubt revisit this (or a variation of this) during our test-driven approach.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/getting-started-testing-wallpaper-updates

Speaking of tests, in this first video of the final part of this series, we are switching back to our test-driven approach and beginning the re-implementation of our Wallpaper Update and Delete features.

As ever, thank you very much for reading, have a great weekend, and happy coding.

Chris