Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX RefererResult bug #975

Closed
wants to merge 7 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import static br.com.caelum.vraptor.view.Results.page;
import static com.google.common.base.Preconditions.checkState;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import javax.enterprise.context.RequestScoped;
Expand Down Expand Up @@ -95,8 +97,18 @@ private String getReferer() {
String referer = request.getHeader("Referer");
checkState(referer != null, "The Referer header was not specified");

String path = request.getContextPath();
return referer.substring(referer.indexOf(path) + path.length());
String refererPath= null;
try {
refererPath = new URL(referer).getPath();
} catch(MalformedURLException e) {
//Maybe a relative path?
refererPath = referer;
}
String ctxPath = request.getContextPath();

//if the context path is not in the beggining we should return the entire path
//this is useful for proxied app servers which hide the ctx path from url
return refererPath.startsWith(ctxPath) ? refererPath.substring(ctxPath.length()) : refererPath;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,89 @@ public void whenRefererMatchesAControllerShouldForwardToIt() throws Exception {
verify(logic).forwardTo(RefererController.class);
verify(controller).index();
}

@Test
public void whenRefererContainsCtxPathStrInTheHostItShouldRedirectCorrectly() throws Exception {
LogicResult logic = mock(LogicResult.class);
RefererController controller = mock(RefererController.class);

Method index = RefererController.class.getMethod("index");
ControllerMethod method = DefaultControllerMethod.instanceFor(RefererController.class, index);

when(request.getHeader("Referer")).thenReturn("http://vraptor.test.com/vrap/anything/ok");
when(request.getContextPath()).thenReturn("/vrap");
when(router.parse("/anything/ok", HttpMethod.GET, request)).thenReturn(method);

doReturn(logic).when(result).use(logic());
when(logic.redirectTo(RefererController.class)).thenReturn(controller);

refererResult.redirect();

verify(logic).redirectTo(RefererController.class);
verify(controller).index();
}

@Test
public void whenRefererContainsCtxPathStrInTheHostItShouldForwardCorrectly() throws Exception {
LogicResult logic = mock(LogicResult.class);
RefererController controller = mock(RefererController.class);

Method index = RefererController.class.getMethod("index");
ControllerMethod method = DefaultControllerMethod.instanceFor(RefererController.class, index);

when(request.getHeader("Referer")).thenReturn("http://vraptor.test.com/vrap/anything/ok");
when(request.getContextPath()).thenReturn("/vrap");
when(router.parse("/anything/ok", HttpMethod.GET, request)).thenReturn(method);

doReturn(logic).when(result).use(logic());
when(logic.forwardTo(RefererController.class)).thenReturn(controller);

refererResult.forward();

verify(logic).forwardTo(RefererController.class);
verify(controller).index();
}

@Test
public void whenRefererDoesNotContainsCtxPathItShouldRedirectCorrectly() throws Exception {
LogicResult logic = mock(LogicResult.class);
RefererController controller = mock(RefererController.class);

Method index = RefererController.class.getMethod("index");
ControllerMethod method = DefaultControllerMethod.instanceFor(RefererController.class, index);

when(request.getHeader("Referer")).thenReturn("http://vraptor.test.com/anything/ok");
when(request.getContextPath()).thenReturn("/vrap");
when(router.parse("/anything/ok", HttpMethod.GET, request)).thenReturn(method);

doReturn(logic).when(result).use(logic());
when(logic.redirectTo(RefererController.class)).thenReturn(controller);

refererResult.redirect();

verify(logic).redirectTo(RefererController.class);
verify(controller).index();
}

@Test
public void whenRefererDoesNotContainsCtxPathItShouldForwardCorrectly() throws Exception {
LogicResult logic = mock(LogicResult.class);
RefererController controller = mock(RefererController.class);

Method index = RefererController.class.getMethod("index");
ControllerMethod method = DefaultControllerMethod.instanceFor(RefererController.class, index);

when(request.getHeader("Referer")).thenReturn("http://vraptor.test.com/anything/ok");
when(request.getContextPath()).thenReturn("/vrap");
when(router.parse("/anything/ok", HttpMethod.GET, request)).thenReturn(method);

doReturn(logic).when(result).use(logic());
when(logic.forwardTo(RefererController.class)).thenReturn(controller);

refererResult.forward();

verify(logic).forwardTo(RefererController.class);
verify(controller).index();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much context to execute a simple check. Maybe it's better to relax visibility of getReferer() to protected and test only this method, what do you think?

and we get an extra extension point.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that was my first commit on VRaptor so I tried to write comprehensive unit tests :-) - but I agree it's too much for something so simple. In addition it's a hard condition to achieve, the strings must match in a little-prob coincidence.

About the extension point, I don't have an opinion - would you expect this class to be extended? If so, then yes it's a good way to maintain its structure (or else people would have to create another method to perform this check, or even put its code within the callers)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your tests are fine =)

it's just that this test class has several tests that could be testing only getReferer(), not the whole redirect or forward methods.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I followed the other methods pattern but we could have simple tests which would check if the returned string matches the expected value and we're good to go. Wanna me to change that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please @valeriolopes! After that change we can merge this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up creating another pull request (976); I really need to stop and play with git (we still use svn here). The changes are there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks @valeriolopes. So I think we close this PR, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looks like the other one embraces everything

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeap! thks


}