JGiven icon indicating copy to clipboard operation
JGiven copied to clipboard

@As not considered in overridden stage method

Open nikowitt opened this issue 8 years ago • 13 comments

public abstract class RelatedToProjectSecurityTest<T extends RelatedToProjectSecurityStage<T, M>, M extends RelatedToProject<?>>
		extends JAFSimpleScenarioTest<T> {
(...)
	@Test
	@UseDataProvider
	public void create(Class<M> clazz, SampleUser sampleUser, boolean success, SampleProject project) {
		given().logged_in_user_is(sampleUser.getUserName());
		when().user_creates_entity_of_$_related_to_$(clazz, project);
		then().access_is_$(success);
	}
(...)

	public static abstract class RelatedToProjectSecurityStage<S extends RelatedToProjectSecurityStage<S, M>, M extends RelatedToProject<?>>
			extends JAFCrudTestStage<S, M> {

		(...)

		public abstract S user_creates_entity_of_$_related_to_$(Class<RelatedToProject<?>> clazz, SampleProject project);
}

which is used in

public class ProjectSecurityTest extends RelatedToProjectSecurityTest<ProjectSecurityStage, RelatedToProject<?>> {
(...)


	@DataProvider
	public static Object[][] create() {
		return createDataProvider(CRUD.CREATE);

	static class ProjectSecurityStage
			extends com.sobis.hzi.sms.tests.security.RelatedToProjectSecurityTest.RelatedToProjectSecurityStage<ProjectSecurityStage, RelatedToProject<?>> {

	(...)

		@Override
		@As("user creates $")
		public ProjectSecurityStage user_creates_entity_of_$_related_to_$(Class<RelatedToProject<?>> clazz, @Hidden SampleProject project) {
			return super.user_creates_entity(Project.class);
		}
	}
}

When I execute ProjectSecurityTest, I expect the following report:

   Given logged in user is "system"
    When user creates project
    Then access is granted

but instead,

	Given logged in user is "system"
    When user creates entity of project related to null
    Then access is granted

is generated. So it seems that the @As is not recognized in this case.

Best regards, Niko

nikowitt avatar Oct 31 '16 12:10 nikowitt

I currently cannot reproduce the issue. I guess, however, that it is related to #63. Which Java version did you use?

janschaefer avatar Nov 01 '16 18:11 janschaefer

Also related: #193

janschaefer avatar Nov 01 '16 18:11 janschaefer

Just to validate: could you make the super-class non-abstract and test whether it works then?

janschaefer avatar Nov 01 '16 18:11 janschaefer

I remembered that I've encountered something similar, but I didn't remember where.

The used Java version is 1.8.0_72.

Dropping the abstract from both RelatedToProjectSecurityTest and RelatedToProjectSecurityStage didn't solve the issue, the report is still not correct.

UPDATE: I've just realized that the provided code snippet does not reflect the situation properly. The overridden method is abstract as well - but I've also ensured that the issue is not related to the abstract method.

When I have a look at your test case, my abstract stage extends from JAFCrudTestStage which is not abstract, and this class also extends from another non-abstract class which again extends... there is a 3-4 level inheritance structure behind my abstract stage class. Maybe the issue is related to that.

nikowitt avatar Nov 02 '16 03:11 nikowitt

Ok, I see. I will try to play around a bit to see whether I can reproduce the issue.

janschaefer avatar Nov 02 '16 06:11 janschaefer

Ok. I could reproduce the issue as follows, but I do not know, whether this is what you meant:

abstract class StageA {
      @As("my custom description")
      abstract void step();
}

class StageB extends StageA {
     void step() {         
     }
}

When I now use StageB, it will report step and not my custom description. If this is what you mean, then this is completely unrelated to #63. In fact, this would not even be a bug, but actually a new feature, to search for annotations at overridden methods :-). The problem here is a bit that Java does not provide a built-in mechanism like @Inherited for classes. But I think it could be implemented otherwise.

janschaefer avatar Nov 02 '16 06:11 janschaefer

I'm not sure this is worth implementing. Why not have the annotated step method in the super class which accesses abstract methods for the subclass to implement?

Airblader avatar Nov 02 '16 06:11 Airblader

Well, the implementation should not be too hard and I also see that the current behavior is surprising and seems to be wrong from a users point of view. The alternative would be to a log some kind of warning, but in that case I also have to check for annotations in overridden methods :-)

janschaefer avatar Nov 02 '16 06:11 janschaefer

So should this work for interface methods too then?

Airblader avatar Nov 02 '16 06:11 Airblader

Good point :-)

janschaefer avatar Nov 02 '16 07:11 janschaefer

If it should work for interfaces as well you'll run into the interesting situation of having multiple interfaces defining the same method but using different @As annotations. :-)

Airblader avatar Nov 02 '16 07:11 Airblader

Ok. I could reproduce the issue as follows, but I do not know, whether this is what you meant:

Yes, this is exactly what I mean :)

nikowitt avatar Nov 02 '16 08:11 nikowitt

Cool. For now, I will only implement this feature for super classes, not interfaces. Supporting interfaces opens too many questions ;-)

janschaefer avatar Nov 02 '16 14:11 janschaefer