Jest Test React Router Link navigation - reactjs

I have the following component that I want to test using Jest Enzyme.
<BrowserRouter>
<Switch>
<Route path='/' component={Home}/>
<Route path='/view' component={View}/>
</Switch>
</BrowserRouter>
class Home extends React.Component {
render {
<Link to='/view'>
<button onClick={() => foo}>View Data</button>
</Link>
}
}
This code is working in application correctly.
However, when I test button click using jest-enzyme, component path or content doesn't change
it('should redirect on button click', () => {
const component= mount(
<MemoryRouter initialEntries={{['/', '/view']}}>
<Route path='/' component={Home}/>
<Route path='/view' component={View}/>
</MemoryRouter>
)
expect(component.find('Home')).toHaveLength(1); //passes
expect(component.find('LinkAnchor').props().href).toEqual('/view'); //this also passes
component.find('button').simulate('click');
expect(component.find('View').toHaveLength(1); //This FAILS
});
My question:
Is only way to test Link could be checking href in it's internal a tag?
Can we test page navigation like it works properly for ?

In this case you probably want to test the history object of the MemoryRouter to be updated when you have clicked the link.
However, you are running into this problem because you're wrapping a button with a link and you are pressing the button not the link.
If you need button styling for your links, you should update the Link component instead:
return (
<Link to='/view' className='buttonClass' onClick={() => foo()} />
);

Related

Create a modal route using React.lazy() component in React Router V6

Is it possible to create a modal route with lazy component pages? By that I mean the <Modal/> is rendered inside the <User/> page instead of being a page of its own.
A modal route is working perfectly with elements:
<Routes>
<Route path="user" element={<User/>}>
<Route path="modal" element={<Modal/>} />
</Route>
</Routes>
But when I use lazy components, the <Modal/> is not rendered inside <User/>. At /user/modal, the <User/> content is gone and the <Modal/> is rendered as a new page:
const User = lazy(() => System.import("./page/User"));
const Modal = lazy(() => System.import("./page/Modal"));
<Routes>
<Route path="user">
<User/>
<Route path="modal">
<Modal/>
</Route>
</Route>
</Routes>
I have the <Outlet/> inside the User Page as per the preview article:
function User = ()=>{
return (
<div><Link to="modal">modal</Link><Outlet/></div>
)
}

How to route to new page in ReactJS

I have a router which has a link to a product details page, problem is, the application is being displayed in a android webview so ... if am viewing a product details page and clicked back, the whole application will exit.
is there a way to make the use go back to the home page ? or I have to implement a back button ?
class App extends React.Component {
render() {
return (
<div>
<Router>
<Switch>
{/* <PrivateRoute exact path="/" component={HomePage} /> */}
<Route exact path="/" component={Home} />
<Template>
<Route path="/:id" component={PropertyTemplate} />
</Template>
</Switch>
</Router>
</div>)
}
}
It's not neccessary to implement backbutton - just this code make work:
history.goBack()
Here is implemented BackButton - just add this in common folder in architecture & reuse.
import React from 'react';
import { withRouter } from 'react-router-dom';
import ReturnIcon from '../../img/tech/return-white-icon.svg'
const GoBack = ({ history }) => <img src={ReturnIcon} onClick={() => history.goBack()} alt="Go back" />;
export default withRouter(GoBack);

React-Router Navigation Appearing Twice On path='/'

In the application the navigation appears single in all the pages except the home which is '/'.
How do I prevent the navigation from appearing twice in the home. Here is a screenshot and the code for the react-router.
Screen Shot OF Double Menu In React-Router:
Here is the code:
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Navigator />
<Switch>
<Route path='/'exact strict component ={HomeIndex} />
<Route path='/Pricing' exact component ={Pricing} />
<Route component={Error404}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
Once check your HomeIndex component, may be you are using <Navigator /> again inside HomeIndex component.

react router parameter loading index route only

So I have my routes defines as follows:
<Route path="/manage" component={Manage}>
<IndexRoute component={Manage}></IndexRoute>
<Route path=":id" component={Edit}></Route>
</Route>
</Route>
Now when I click on a button in my Manage component I call following function:
handleEditClick(e) {
e.preventDefault();
let selectedId= this.state.selectedId;
this.props.router.replace("/manage/" + selectedId);
},
My browser does display me the correct link but my component is not loaded as should. It only renders me the Manage component and not the Edit component.
Am I missing something here?
UPDATE
changing the child route to <Route path="/manage/:id" component={Edit}></Route> also loads me the Manage component
UPDATE 2
if I do not use child routes but in stead create them on the same level, the Edit component does render, but I'd like to use child routes.
On your render() you need a {this.props.children} ... it's where React router knows where to put child Component
In your routes
<Route path="/manage" component={Manage}>
<IndexRoute component={Manage}></IndexRoute>
<Route path=":id" component={Edit}></Route>
</Route>
If you navigate to /manage/:id, React Router renders Manager and Edit components... but where to put Edit?
So
you need to have something like this.
class Manager extends Component {
render(){
return (
<div>
Hello
{this.props.children}
</div>
);
}
}
So React Router knows to put Edit along side when you go to /manage/:id
<div>
Hello
<Edit />
</div>

How to link to a nested route in React?

I have an AngularJS background, and started to play around with React. I'm using the react-router and want have basically this setup:
Template
export default ( props ) => {
return (
<div>
<Navbar></Navbar>
{ props.children }
</div>
);
}
Routing in App.js
<Router>
<Route path="/" component={Template}>
<IndexRoute component={RestaurantRoulette} />
<Route name="workspace" path="workspace(/:workspace_id)" component={RestaurantRoulette}>
<Route name="run" path="run" component={Run}></Route>
</Route>
</Route>
</Router>
Navbar
<ul className="navigation">
<li>RestaurantRoulette</li>
<Link to="run">Run</Link>
<li>Save</li>
</ul>
What I want
When I am in localhost:8080/workspaces/444 I want to click on the Run Link, and navigate to localhost:8080/workspaces/444/run
What is the current status
If I manually type the url localhost:8080/workspaces/444/run, everything works fine. But when I click on the Link in the navbar, I get to localhost:8080/run.
Can somebody tell me how this works? How this is all connected?
I think the Link tag should be like that:
<Link to={'workspaces/' + this.props.workspace_id + '/run'}>Run</link>
you should get the workspace_id from path in Template, and pass it to the NavBar component

Resources