You've probably written code similar to the examples below a good number of times. Maybe you've even asked AI to do some of these things for you recently.
But could you still do them yourself, without AI or even a quick Google search?
Rules :
- No AI assistants, Google, Stack Overflow, or documentation.
- Use JavaScript (no frameworks or third-party libraries).
- You can run your code as many times as you need.
- Aim to complete all five challenges in 60 minutes.
Lets see how comfortable you are working without assistance. Have fun!
Challenge 1: Find the Bug in This Shopping Cart
Difficulty: Easy
A customer reports that their shopping cart sometimes displays the wrong total. You've been given the following function:
const cart = [ { name: "Keyboard", price: 50, quantity: 2 }, { name: "Mouse", price: 25, quantity: 0 }, { name: "Monitor", price: 200, quantity: 1 } ]; function calculateTotal(cart) { return cart.reduce((total, item) => { if (item.quantity === 0) { return 0; } return total + item.price * item.quantity; }, 0); } console.log(calculateTotal(cart)); Your Task
- Identify what's causing the incorrect total.
- Fix the function without removing the
reduce()method. - Make sure the function works even when some products have a quantity of zero.
Expected output:
300 Bonus: Explain why the bug might not be noticed with certain cart arrangements.
Challenge 2: Process a Messy API Response
Difficulty: Easy–Medium
You're building a sales dashboard, and your backend returns the following data:
const response = { orders: [ { id: 1, status: "paid", total: 120 }, { id: 2, status: "pending", total: 75 }, { id: 3, status: "paid", total: 50 }, { id: 4, status: "refunded", total: 30 }, { id: 5, status: "paid", total: null }, { id: 6, status: "paid" } ] }; Your Task
Write a function named getSalesSummary(response) that returns an object containing:
-
paidOrders: The number of orders with a status of"paid". -
revenue: The sum of valid numeric totals from paid orders. -
averageOrderValue: Revenue divided by the number of paid orders that have valid numeric totals.
Requirements:
- Ignore pending and refunded orders when calculating revenue.
- Missing or
nulltotals should not contribute to revenue or the average. - They should still count toward
paidOrdersif their status is"paid". - Return an average of
0if there are no paid orders with valid numeric totals. - Don't modify the original response.
Expected output:
{ paidOrders: 4, revenue: 170, averageOrderValue: 85 } Bonus: What happens if response.orders is an empty array?
Challenge 3: Build a Search Bar Without a Framework
Difficulty: Medium
You've been given a simple product page. Your task is to make its search bar functional using nothing but vanilla JavaScript.
Starter HTML
<input id="search" type="text" placeholder="Search products..." /> <ul id="products"> <li>Wireless Mouse</li> <li>Mechanical Keyboard</li> <li>USB-C Cable</li> <li>Mouse Pad</li> <li>Gaming Monitor</li> </ul> <p id="empty" hidden>No products found.</p> <script> // Write your JavaScript here </script> Your Task
Implement a search feature that:
- Filters products as the user types.
- Ignores uppercase and lowercase differences.
- Supports partial matches.
- Shows all products when the search field is empty.
- Displays "No products found." when nothing matches.
Expected behavior:
| Search input | Visible products |
|---|---|
mouse | Wireless Mouse, Mouse Pad |
KEYBOARD | Mechanical Keyboard |
usb | USB-C Cable |
xyz | No products found |
| Empty input | All five products |
Bonus: Make the search ignore leading and trailing spaces.
No React, Vue, jQuery, or other frameworks. Just JavaScript and the DOM.
Challenge 4: Handle a Failing API
Difficulty: Medium
You're building a profile page that retrieves user information from an API.
Unfortunately, the API isn't always reliable.
Here's a mock API function you can use:
let attempts = 0; function fetchUser() { return new Promise((resolve, reject) => { setTimeout(() => { attempts++; if (attempts === 1) { reject(new Error("Network error")); } else { resolve({ name: "Alex", role: "Developer" }); } }, 1000); }); } The first request will fail. The second will succeed.
Starter HTML
<button id="load">Load User</button> <button id="retry" hidden>Retry</button> <p id="status"></p> <div id="profile"></div> <script> // Place fetchUser() and your code here </script> Your Task
Implement the following behavior:
- Clicking "Load User" calls
fetchUser(). - While waiting, display
"Loading...". - If the request fails, display the error message.
- Show the "Retry" button when an error occurs.
- Clicking "Retry" attempts the request again.
- On success, display the user's name and role.
- Prevent users from triggering multiple requests while one is still loading.
Expected flow:
User clicks "Load User" | v Loading... | v Error: Network error | v User clicks "Retry" | v Loading... | v Alex - Developer You can use any approach, but the final solution should handle both success and failure correctly.
Bonus: Clear the previous error message when retrying.
Challenge 5: Prevent Double Bookings
Difficulty: Medium
Imagine you're working on a booking application for a small sports venue.
Customers can reserve a court for a specific period, but two reservations must never overlap.
You're given the following existing bookings:
const bookings = [ { start: "09:00", end: "10:00" }, { start: "11:00", end: "12:00" }, { start: "14:00", end: "15:30" } ]; Your Task
Write a function:
function canBook(bookings, newBooking) { // Your code here } The function should return:
-
trueif the requested time slot is available. -
falseif the requested time slot overlaps an existing booking or is invalid.
Requirements:
- A new booking must not overlap any existing booking.
- The booking's end time must be later than its start time.
- A booking can start exactly when another booking ends.
- A booking can end exactly when another booking starts.
- Existing bookings might not be sorted.
- The function must not modify the original bookings.
Assumptions: All bookings are for the same day, use valid zero-padded 24-hour HH:MM times, and do not cross midnight. A booking occupies its start time but not its end time.
Test Cases
Your function should produce these results:
canBook(bookings, { start: "09:30", end: "10:30" }); // false canBook(bookings, { start: "10:00", end: "11:00" }); // true canBook(bookings, { start: "13:00", end: "14:30" }); // false canBook(bookings, { start: "15:30", end: "16:00" }); // true canBook(bookings, { start: "13:00", end: "12:00" }); // false Bonus: How would you prevent two users from successfully booking the same slot if they submit their requests at almost exactly the same time?
You don't need to implement the bonus. Just think about what would have to change beyond this function.
So, How Did You Do?
How many did you manage to complete?
Did you struggle with remembering syntax, understanding the logic, or handling unexpected edge cases?
Personally, I think there's a difference between understanding code when you read it and actually being able to write it yourself. And as AI becoming such a normal part of development, I thought it would be interesting to test that difference. And of course dont take this challenge too seriously and keep improving. :)
Share your score out of 5 in the comments, and let me know which challenge gave you the most trouble.


