I graduated from a coding boot camp earlier this year and I am currently looking for a new job. One day I received an email letting me know that Shopify has a remote internship program and that the applications for the soonest-starting back-end engineer internship cohort were closing in 5 days. I had never seriously considered any elite internships before as I believed they were hard to get into unless you were a college cs grad and I am not. Upon further inspection, the Shopify internship was inclusive of non-grads so I decided to apply and found myself greeted with an unexpected entrance requirement; completion of a programming challenge.
UPDATE! I got the interview!!!!! and I wrote about it too
Project Requirements
The prompt for the coding challenge was to “Build an Image repository”. The project requirements were no less open-ended, and more-so examples of functionality to build into the app. I found them inviting and welcoming rather than restrictive or prescriptive. The impression I got was that Shopify cares less about a candidate reversing a linked list and more about how a candidate gets things done in a short amount of time, what they prioritize, what they’ll compromise on, and what they won’t.
My approach
My first step in planning this project was to decide on an interpretation of what was meant by “build an image repository”. The Oxford definition of a repository is a place, building, or receptacle where things are or may be stored. To me this sounds like google drive, so that’s what I went with. In the project requirements, there were examples of several “ideas, or; branches of functionality one could choose to focus on. They suggested focusing on only one or two: Search, Add, Delete and Sell/Buy.
I decided to go with Add and Delete as they would be the easiest and thus the fastest areas of focus to complete. The full versions of those ideas included, access control and single or bulk upload and delete. In addition to those two, I decided to add a tagging system to color outside of the lines a little bit.
I knew I would use Ruby on Rails from the start as that is where my experience is and Shopify is one of the largest users/supporters of Ruby on Rails in the world. Knowing I would use Rails I also expected I would use ActiveStorage: Rail’s built-in file upload and management which I had zero experience with. I did not let my lack of experience phase me and I decided to move forward as follows:
1. Get the “business Logic” working, i.e. model relationships, routes, views, tests, etc.
2. Add ActiveStorage and figure it out.
3. Polish and submit i.e. flash messages, front-end styling, empty index messages, etc.
I was in a bit of a crunch for time as I had 5 days to complete the challenge, (luckily It was over a long weekend) so I decided to just use Rail’s Action View Templates for the front-end, typically I would have created an API back-end and a react client but I felt that approach would have taken more time, offered nothing towards meeting the requirements and was a bit irrelevant as I was applying to a back-end internship. In addition, I wanted to build this project in a way that I could meet the requirements quickly and then spend any extra time crossing my t’s and dotting my i’s.
Testing
Before this project I had written some tests for Rails using MiniTest and RSpec as well as Mocha and Chai for express.js, however, I had never written tests as comprehensive as what I believe was expected from Shopify. I value tests and I believe thoroughly that testing code creates better, stronger code, and prevents time burning scope drift yet I faced internal resistance every time I approached the subject, I don’t know if I subconsciously felt like tests were too hard for me or what but I was happily proven wrong by this project.
For testing I used RSpec and It was EASY, vscode makes debugging your tests as simple as adding a config to your launch file and pressing F5, the only issue I ran into was the default launch configuration needs to be pointed to your installation of RSpec which caused me some trouble before I realized what the issue was.
Day 1: 09–17
Friday, the first day was light, this was the day I found the application, and most of the work I did was planning. I also created a little sample rails app to get my hands dirty with ActiveStorage, I thought I should get a higher-level view of the basic functionality to make sure I could plan accordingly even though I didn’t intend to integrate actual file management immediately.
I decided on a basic structure with three models: Users, Images, and Tags. Using a one-to-many relationship between Users & Images as well as Users & Tags would allow a user to manage Images and Tags separately while a join table between Images and Tags allows a user to associate images with a given tag.
At this point, I was stoked to jump in and give as much effort as I could for this project. I figured even if I didn’t get the internship I would still have a nice addition to my portfolio and something to write a blog about so It was a win-win situation.
At the end of the day, I created a new repository and pushed it up to GitHub: Dingo
Day 2: 08–19
Saturday, day two was pure focus and productivity. I wrote unit tests for the models, their validations, and their relationships. I built out the routes and controllers and began writing integration tests. This was a bit more complicated than the model unit tests but after a bit of experimentation, I figured it out and went full speed ahead. Today I also began building the views, completely lacking styles but completely functional. At the end of this day, I had most of the busywork of user authentication and the like as well as most of the main functionality working and passing tests. I hardly slept that night, my excitement reminiscent of the night before a field trip in grade school.
Day 3: 09–19
Sunday I added ActiveStorage and finalized the routes, with the MVP up and running I shifted my focus to the front end. After some basic styling with bootstrap, I moved to refactoring the views, extracting forms and components into partials, and making the header partial accept dynamic content. At the end of the day, my bootstrap integration was imperfect and the JavaScript was not working, but I was tired and called it a night.
Day 4: 09–20
Monday The fourth day was all about dotting I’s and crossing T’s. I added pundit for authorization and added ApplicationController methods to redirect based on whether the User is logged in or not. I added a partial to display flash messages and added empty messages to the image, tag, and image-by-tag indexes. I fixed the bootstrap integration by following this video. I also fixed my launch file configuration to use the debugger to run and debug my tests using this stackoverflow post. This day was spent mostly on Testing.
Day 5: 09–21
Tuesday The final day consisted of me stepping on several rakes. I ran into a typo-caused bug in one of the tests that took me an embarrassing amount of time to root out. I re-read the requirements file and realized I had neglected to add an element of functionality suggested in the areas of focus I chose; bulk upload and delete. I quickly wrote a few tests, built a new view, altered the form for uploading images, and added a few navigation links to the header, and boom I had satisfactorily met the requirements. I crossed my fingers and submitted my application.
Conclusion
This was overall a great experience for me and though I am hopeful I will get an interview I feel like I got heaps of value out of the experience. This is the most thoroughly I have ever planned or tested a project and I have gained a lot of insight into not only what I am capable of doing in a short amount of time but how to do a lot in a short amount of time. I think I will make a habit of imposing short time frames on myself to develop my planning skills. Here is my code if you’d like to take a look.
UPDATE I got the interview, you can read about it here
If you enjoyed my writing feel free to check out my website and connect with me on LinkedIn