- Clone this repository
- Install dependencies with
yarn
- Run application with
yarn start
- App is now running at http://localhost:3000.
We are starting on master branch to make all our changes.
You can checkout final
branch to see all changes.
We have to be gold standard in the Cryptocurrency conversion industry. Lets implement some tests:
To set your tests app, install @testing-library/react
, @testing-library/user-event
, and @testing-library/jest-dom
with either yarn add <your-dep>
or npm install <your-dep>
.
-
Start by making sure our core functionality behaves as expected. Create tests for the
<Converter />
component that checks titles and labels are rendered as expected. For that you should use therender
function on the@testing-library/react
. This docs might be useful https://testing-library.com/docs/react-testing-library/api#render -
Time to test some interactions too. Are euros converted as expected by our
<Context />
? For that you can use@testing-library/user-event
. Docs on this repo might help https://github.com/testing-library/user-event -
Our Product Owner wants to make sure that users feel the pain of not being premium. Test if the app interrupts the user as expected. Use mock functions. https://jestjs.io/docs/en/mock-functions
-
Our PO thinks is fair to make sure that premium users are not bothered by banners or confirmation modals. Use mock functions too
-
Industry is growing. We have to be able to ship our app with different configurations. Make our app decide from
props
the conversors (and their convertion rate) shown, as well as the non premium conversor threshold to show the banner. -
Update and add the test cases that you find convenient.
PremiumLabel
component is already a functional component, so we can already use hooks here. Change it's background when users have selected the "Dark Theme".- We can simplify
Amount
component converting it to a functional component, again usinguseContext
hook to get our global context. - Although we have an internal state in
Converter
component, we can useuseState
hook to simplify our component. Lets convert it to a functional component. - Our
App
component usescomponentDidUpdate
lifecycle method to react to state changes. We can make it a functional component by using theuseEffect
hook. - With our first release we allowed users to change the application theme with "Dark" and "Light" modes. Let's add an "Auto" option and create a custom hook,
usePreferredColorScheme
, that uses match media API to guess which will be the desired theme. - When our page is reloaded users lose they premium subscription and their theme configuration. Create a
useCachedState(key, defaultValue)
that stores this values insidelocalStorage
and replace theuseState
hooks forselectedTheme
andpremium
. Warning: we do not want to recalculate the value of localStorage everytime this hook is called. - For some reason Ethereum is becoming our most used cryptocurrenty, and we want this converter to work as fast as possible. Add an
focusOnMount
property to theConverter
component (and theAmount
component) and use theuseRef
hook to focus the Ethereum input automatically. - We found that this focus on mount behaviour is really useful, extract it to a
useFocusOnMount
hook so we can reuse during the following weeks.
You can start from your own App from last week, or simply git checkout start
to have an app ready to work with.
- Our Product Owner foresees a demand in conversion for other cryptocurrencies: extract the convertion logic into a
<Converter />
component that takes acryptoName
and aexchangeRate
. We can drop the crash to zero after 5 seconds functionality. - Add a second converter to our app, one for Ethereum $ETH with a
1.2
exchangeRate
. Add as many as you want. - Our design team finds the lack of a title per
<Converter />
a usuabillity problem. Allow the<Converter />
component to render some custom markup to render it at the top of the component. - Monetization is key. Add an alert to warn the user about our freemium conversion model after 5 convertions are performed in any of the components in our app.
- We need a way to let our users become Premium Members. Implement a Become Premium button that removes the just implemented alert and adds a
💎 Premium conversion
message.
-
Add a number input with a label, "Euros".
-
Extract the input into a separate component called
<Amount />
that takes aname
(eg. "Euros") prop. -
(Optional) If it is not already, convert
<Amount />
into a class-based component. -
Teach
<Amount />
input to show a red outline for negative amounts. -
Make
<Amount />
a controlled component (ie. pass it itsvalue
as a prop). -
Add a second, read-only
<Amount />
component that shows $BTC instead of Euros; use this function to get the exchange rate:function exchangeRate() { return Math.random() * 10000; }
-
Use
setTimeout
to make the $BTC price crash to zero after 5 seconds of inactivity. -
Use
React.createContext()
to provide a dark/light theme toggle.