You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/07/10 18:53:10 UTC

[isis] branch v2 updated: ISIS-2123 resurrects simpleapp-module-simple tests

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new edc8768  ISIS-2123 resurrects simpleapp-module-simple tests
edc8768 is described below

commit edc876838925731f03723e4b4f16b998bc24084c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jul 10 20:52:59 2019 +0200

    ISIS-2123 resurrects simpleapp-module-simple tests
    
    Yet some of them fail, because we disabled the fixture teardown logic in
    favor of the auto rollback for Spring powered integration tests.
---
 .../ExceptionRecognizerTranslate.java              |  28 +--
 .../IsisIntegrationTestAbstact.java                |  99 ++++++++++
 .../isis/integtestsupport/ThrowableMatchers.java   |  31 ++-
 .../components/AuthenticationManagerNull.java      |   1 -
 .../components/AuthorizationManagerAllowAll.java   |   1 -
 examples/apps/simpleapp/application/pom.xml        |  13 +-
 .../application/manifest/SimpleAppManifest.java    |   4 +-
 examples/apps/simpleapp/module-simple/pom.xml      |   6 +
 .../simple/dom/impl/SimpleObjects_Test.java        |   2 -
 .../integtests/SimpleModuleIntegTestAbstract.java  |  14 +-
 .../SimpleModuleManifestForTesting.java}           |  29 +--
 .../integtests/tests/SimpleObject_IntegTest.java   | 211 +++++++++++----------
 .../integtests/tests/SimpleObjects_IntegTest.java  | 173 ++++++++---------
 extensions/fixtures/pom.xml                        |   6 +
 .../IsisIntegrationTestAbstactWithFixtures.java}   |  98 +---------
 15 files changed, 369 insertions(+), 347 deletions(-)

diff --git a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ExceptionRecognizerTranslate.java b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ExceptionRecognizerTranslate.java
index 84373bb..1ddd3bd 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ExceptionRecognizerTranslate.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ExceptionRecognizerTranslate.java
@@ -1,18 +1,20 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *        http://www.apache.org/licenses/LICENSE-2.0
  *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
  */
 package org.apache.isis.integtestsupport;
 
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/IsisIntegrationTestAbstact.java b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/IsisIntegrationTestAbstact.java
new file mode 100644
index 0000000..aa0ef7b
--- /dev/null
+++ b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/IsisIntegrationTestAbstact.java
@@ -0,0 +1,99 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.integtestsupport;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.services.factory.FactoryService;
+import org.apache.isis.applib.services.metamodel.MetaModelService;
+import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.applib.services.sessmgmt.SessionManagementService;
+import org.apache.isis.applib.services.user.UserService;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.xactn.TransactionService;
+
+/**
+ * Convenient base class to extend for integration tests. 
+ *  
+ * @since 2.0
+ */
+public abstract class IsisIntegrationTestAbstact {
+
+    /**
+     * Convenience method, simply delegates to {@link WrapperFactory#wrap(Object)}
+     */
+    protected <T> T wrap(final T obj) {
+        return wrapperFactory.wrap(obj);
+    }
+
+    /**
+     * Convenience method, synonym of {@link #wrap(Object)}
+     */
+    protected <T> T w(final T obj) {
+        return wrap(obj);
+    }
+
+    /**
+     * Convenience method, simply delegates to {@link WrapperFactory#wrapMixin(Class, Object)}.
+     */
+    protected <T> T wrapMixin(final Class<T> mixinClass, final Object mixedIn) {
+        return wrapperFactory.wrapMixin(mixinClass, mixedIn);
+    }
+
+    /**
+     * Convenience method, synonym for {@link #wrapMixin(Class, Object)}.
+     */
+    protected <T> T wm(final Class<T> mixinClass, final Object mixedIn) {
+        return wrapMixin(mixinClass, mixedIn);
+    }
+
+    /**
+     * Convenience method, simply delegates to {@link FactoryService#mixin(Class, Object)}.
+     */
+    protected <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
+        return factoryService.mixin(mixinClass, mixedIn);
+    }
+
+    /**
+     * Convenience method, synonym for {@link #mixin(Class, Object)}.
+     */
+    protected <T> T m(final Class<T> mixinClass, final Object mixedIn) {
+        return factoryService.m(mixinClass, mixedIn);
+    }
+
+    /**
+     * For convenience of subclasses, remove some boilerplate
+     */
+    protected <T> T unwrap(final T obj) {
+        return wrapperFactory.unwrap(obj);
+    }
+    
+    // -- DEPENDENCIES
+
+    @Inject protected MetaModelService metaModelService;
+    @Inject protected FactoryService factoryService;
+    @Inject protected ServiceRegistry serviceRegistry;
+    @Inject protected RepositoryService repositoryService;
+    @Inject protected UserService userService;
+    @Inject protected WrapperFactory wrapperFactory;
+    @Inject protected TransactionService transactionService;
+    @Inject protected SessionManagementService sessionManagementService;
+	
+}
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ThrowableMatchers.java b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ThrowableMatchers.java
index 2e97591..6dc1c3b 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ThrowableMatchers.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/ThrowableMatchers.java
@@ -1,18 +1,20 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *        http://www.apache.org/licenses/LICENSE-2.0
  *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
  */
 package org.apache.isis.integtestsupport;
 
@@ -31,9 +33,6 @@ public class ThrowableMatchers {
             @Override
             protected boolean matchesSafely(final Throwable throwable) {
                 final List<Throwable> causalChain = _Exceptions.getCausalChain(throwable); // non null result
-
-                // legacy of return !FluentIterable.from(causalChain).filter(type).isEmpty();
-
                 return causalChain.stream().filter(t->t.getClass().equals(type)).findAny().isPresent();
             }
 
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthenticationManagerNull.java b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthenticationManagerNull.java
index 1b2cf0d..caa4752 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthenticationManagerNull.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthenticationManagerNull.java
@@ -16,7 +16,6 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
 package org.apache.isis.integtestsupport.components;
 
 import org.apache.isis.commons.internal.components.Noop;
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthorizationManagerAllowAll.java b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthorizationManagerAllowAll.java
index 00b8801..7f32838 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthorizationManagerAllowAll.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/integtestsupport/components/AuthorizationManagerAllowAll.java
@@ -16,7 +16,6 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
 package org.apache.isis.integtestsupport.components;
 
 import org.apache.isis.applib.Identifier;
diff --git a/examples/apps/simpleapp/application/pom.xml b/examples/apps/simpleapp/application/pom.xml
index 7bc624b..38bd321 100644
--- a/examples/apps/simpleapp/application/pom.xml
+++ b/examples/apps/simpleapp/application/pom.xml
@@ -71,16 +71,17 @@
         </dependency>
         
         <!-- PERSISTENCE -->
-        
+
+		<dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+        </dependency>
+
+<!--        
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
         </dependency>
-<!--
-        <dependency>
-            <groupId>org.hsqldb</groupId>
-            <artifactId>hsqldb</artifactId>
-        </dependency>
         <dependency>
             <groupId>postgresql</groupId>
             <artifactId>postgresql</artifactId>
diff --git a/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java b/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java
index 1c10a57..5222a4e 100644
--- a/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java
+++ b/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java
@@ -43,12 +43,12 @@ import domainapp.application.DomainAppApplicationModule;
 import domainapp.modules.simple.SimpleModule;
 
 /**
- * Makes the integral parts of the 'hello world' web application.
+ * Makes the integral parts of the 'simple app' web application.
  */
 @Configuration
 @PropertySources({
 	@PropertySource("classpath:/domainapp/application/manifest/isis-non-changing.properties"),
-    @PropertySource(name=Presets.H2InMemory, factory = Presets.Factory.class, value = { "" }),
+    @PropertySource(name=Presets.HsqlDbInMemory, factory = Presets.Factory.class, value = { "" }),
     @PropertySource(name=Presets.NoTranslations, factory = Presets.Factory.class, value = { "" }),
     @PropertySource(name=Presets.DataNucleusAutoCreate, factory = Presets.Factory.class, value = { "" }),
 })
diff --git a/examples/apps/simpleapp/module-simple/pom.xml b/examples/apps/simpleapp/module-simple/pom.xml
index efd4f82..d6dbf16 100644
--- a/examples/apps/simpleapp/module-simple/pom.xml
+++ b/examples/apps/simpleapp/module-simple/pom.xml
@@ -77,6 +77,12 @@
 			<scope>test</scope>
 		</dependency>
 
+<!--         <dependency> -->
+<!--             <groupId>com.h2database</groupId> -->
+<!--             <artifactId>h2</artifactId> -->
+<!--             <scope>test</scope> -->
+<!--         </dependency> -->
+
 		<dependency>
 			<groupId>org.hsqldb</groupId>
 			<artifactId>hsqldb</artifactId>
diff --git a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
index 5fb9ff9..6395ec5 100644
--- a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
+++ b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
@@ -34,8 +34,6 @@ import org.apache.isis.applib.services.repository.RepositoryService;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-//TODO [ahuber] this test is still on JUnit 4 because it uses org.junit.Rule, 
-//which no longer exists with JUnit 5
 public class SimpleObjects_Test {
 
     @Rule
diff --git a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleIntegTestAbstract.java b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleIntegTestAbstract.java
index 294084e..9eb892e 100644
--- a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleIntegTestAbstract.java
+++ b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleIntegTestAbstract.java
@@ -18,12 +18,16 @@
  */
 package domainapp.modules.simple.integtests;
 
-public abstract class SimpleModuleIntegTestAbstract /*extends IntegrationTestJupiter*/ {
+import org.apache.isis.extensions.fixtures.IsisIntegrationTestAbstactWithFixtures;
+import org.springframework.boot.test.context.SpringBootTest;
 
-  //FIXME[2112] needs migration
-//    public SimpleModuleIntegTestAbstract() {
-//        super(new SimpleModule().withConfigurationProperty("isis.objects.editing", "false"));
-//    }
+@SpringBootTest(
+		classes = SimpleModuleManifestForTesting.class, 
+		properties = {
+				"isis.objects.editing=false"
+		})
+public abstract class SimpleModuleIntegTestAbstract extends IsisIntegrationTestAbstactWithFixtures {
 
 
 }
+
diff --git a/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleManifestForTesting.java
similarity index 65%
copy from examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java
copy to examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleManifestForTesting.java
index 1c10a57..fdc73f3 100644
--- a/examples/apps/simpleapp/application/src/main/java/domainapp/application/manifest/SimpleAppManifest.java
+++ b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/SimpleModuleManifestForTesting.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package domainapp.application.manifest;
+package domainapp.modules.simple.integtests;
 
 import javax.inject.Singleton;
 
@@ -26,9 +26,7 @@ import org.apache.isis.config.beans.WebAppConfigBean;
 import org.apache.isis.extensions.fixtures.IsisBootFixtures;
 import org.apache.isis.jdo.IsisBootDataNucleus;
 import org.apache.isis.runtime.spring.IsisBoot;
-import org.apache.isis.security.shiro.IsisBootSecurityShiro;
-import org.apache.isis.viewer.restfulobjects.IsisBootWebRestfulObjects;
-import org.apache.isis.viewer.wicket.viewer.IsisBootWebWicket;
+import org.apache.isis.security.IsisBootSecurityBypass;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.ComponentScan.Filter;
@@ -37,48 +35,37 @@ import org.springframework.context.annotation.FilterType;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.PropertySource;
 import org.springframework.context.annotation.PropertySources;
-import org.springframework.core.io.ClassPathResource;
 
-import domainapp.application.DomainAppApplicationModule;
 import domainapp.modules.simple.SimpleModule;
 
+
 /**
- * Makes the integral parts of the 'hello world' web application.
+ * Makes the integral parts of the 'module-simple' integration tests.
  */
 @Configuration
 @PropertySources({
-	@PropertySource("classpath:/domainapp/application/manifest/isis-non-changing.properties"),
-    @PropertySource(name=Presets.H2InMemory, factory = Presets.Factory.class, value = { "" }),
-    @PropertySource(name=Presets.NoTranslations, factory = Presets.Factory.class, value = { "" }),
+	//@PropertySource("classpath:/domainapp/application/manifest/isis-non-changing.properties"),
+	@PropertySource(name=Presets.HsqlDbInMemory, factory = Presets.Factory.class, value = { "" }),
     @PropertySource(name=Presets.DataNucleusAutoCreate, factory = Presets.Factory.class, value = { "" }),
 })
 @Import({
     IsisBoot.class,
-    IsisBootSecurityShiro.class,
+    IsisBootSecurityBypass.class,
     IsisBootDataNucleus.class,
-    IsisBootWebRestfulObjects.class,
-    IsisBootWebWicket.class,
     IsisBootFixtures.class
 })
 @ComponentScan(
         basePackageClasses= {
-                DomainAppApplicationModule.class,
                 SimpleModule.class
         },
         includeFilters= {
                 @Filter(type = FilterType.CUSTOM, classes= {IsisBeanScanInterceptorForSpring.class})
         })
-public class SimpleAppManifest {
+public class SimpleModuleManifestForTesting {
     
    @Bean @Singleton
    public WebAppConfigBean webAppConfigBean() {
        return WebAppConfigBean.builder()
-               .menubarsLayoutXml(new ClassPathResource("menubars.layout.xml", this.getClass()))
-               .brandLogoHeader("/images/gift_48.png")
-               .applicationCss("css/application.css")
-               .applicationJs("scripts/application.js")
-               .applicationName("Apache Isis Simple App")
-               .faviconUrl("/images/favicon.png")
                .build();
    }
    
diff --git a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
index e88490c..762d1d5 100644
--- a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
+++ b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
@@ -24,7 +24,7 @@ import javax.inject.Inject;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-
+import org.springframework.transaction.annotation.Transactional;
 import org.apache.isis.applib.services.title.TitleService;
 import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.applib.services.wrapper.InvalidException;
@@ -39,112 +39,113 @@ import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+@Transactional
 public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
 
     SimpleObject simpleObject;
-  //FIXME[2112] needs migration
-//    @BeforeEach
-//    public void setUp() {
-//        // given
-//        simpleObject = fixtureScripts.runBuilderScript(SimpleObject_persona.FOO.builder());
-//    }
-//
-//    public static class Name extends SimpleObject_IntegTest {
-//
-//        @Test
-//        public void accessible() {
-//            // when
-//            final String name = wrap(simpleObject).getName();
-//
-//            // then
-//            assertThat(name).isEqualTo(simpleObject.getName());
-//        }
-//
-//        @Test
-//        public void not_editable() {
-//        	
-//        	// expect
-//            assertThrows(DisabledException.class, ()->{
-//            
-//            	// when
-//            	wrap(simpleObject).setName("new name");
-//            	
-//            });
-//        }
-//
-//    }
-//
-//    public static class UpdateName extends SimpleObject_IntegTest {
-//
-//        @Test
-//        public void can_be_updated_directly() {
-//
-//            // when
-//            wrap(simpleObject).updateName("new name");
-//            transactionService.nextTransaction();
-//
-//            // then
-//            assertThat(wrap(simpleObject).getName()).isEqualTo("new name");
-//        }
-//
-//        @Test
-//        public void failsValidation() {
-//
-//        	// expect
-//        	InvalidException cause = assertThrows(InvalidException.class, ()->{
-//            
-//            	// when
-//        		wrap(simpleObject).updateName("new name!");
-//            	
-//            });
-//        	
-//        	// also expect
-//        	assertThat(cause.getMessage(), containsString("Exclamation mark is not allowed."));
-//        	
-//        }
-//    }
-//
-//
-//    public static class Title extends SimpleObject_IntegTest {
-//
-//        @Inject
-//        TitleService titleService;
-//
-//        @Test
-//        public void interpolatesName() {
-//
-//            // given
-//            final String name = wrap(simpleObject).getName();
-//
-//            // when
-//            final String title = titleService.titleOf(simpleObject);
-//
-//            // then
-//            assertThat(title).isEqualTo("Object: " + name);
-//        }
-//    }
-//
-//    public static class DataNucleusId extends SimpleObject_IntegTest {
-//
-//        @Test
-//        public void should_be_populated() {
-//            // when
-//            final Long id = mixin(Persistable_datanucleusIdLong.class, simpleObject).prop();
-//
-//            // then
-//            assertThat(id).isGreaterThanOrEqualTo(0);
-//        }
-//    }
-//
-//    public static class DataNucleusVersionTimestamp extends SimpleObject_IntegTest {
-//
-//        @Test
-//        public void should_be_populated() {
-//            // when
-//            final Timestamp timestamp = mixin(Persistable_datanucleusVersionTimestamp.class, simpleObject).prop();
-//            // then
-//            assertThat(timestamp).isNotNull();
-//        }
-//    }
+
+    @BeforeEach
+    public void setUp() {
+        // given
+        simpleObject = fixtureScripts.runBuilderScript(SimpleObject_persona.FOO.builder());
+    }
+
+    public static class Name extends SimpleObject_IntegTest {
+
+        @Test
+        public void accessible() {
+            // when
+            final String name = wrap(simpleObject).getName();
+
+            // then
+            assertThat(name).isEqualTo(simpleObject.getName());
+        }
+
+        @Test
+        public void not_editable() {
+        	
+        	// expect
+            assertThrows(DisabledException.class, ()->{
+            
+            	// when
+            	wrap(simpleObject).setName("new name");
+            	
+            });
+        }
+
+    }
+
+    public static class UpdateName extends SimpleObject_IntegTest {
+
+        @Test
+        public void can_be_updated_directly() {
+
+            // when
+            wrap(simpleObject).updateName("new name");
+            transactionService.nextTransaction();
+
+            // then
+            assertThat(wrap(simpleObject).getName()).isEqualTo("new name");
+        }
+
+        @Test
+        public void failsValidation() {
+
+        	// expect
+        	InvalidException cause = assertThrows(InvalidException.class, ()->{
+            
+            	// when
+        		wrap(simpleObject).updateName("new name!");
+            	
+            });
+        	
+        	// also expect
+        	assertThat(cause.getMessage(), containsString("Exclamation mark is not allowed."));
+        	
+        }
+    }
+
+
+    public static class Title extends SimpleObject_IntegTest {
+
+        @Inject
+        TitleService titleService;
+
+        @Test
+        public void interpolatesName() {
+
+            // given
+            final String name = wrap(simpleObject).getName();
+
+            // when
+            final String title = titleService.titleOf(simpleObject);
+
+            // then
+            assertThat(title).isEqualTo("Object: " + name);
+        }
+    }
+
+    public static class DataNucleusId extends SimpleObject_IntegTest {
+
+        @Test
+        public void should_be_populated() {
+            // when
+            final Long id = mixin(Persistable_datanucleusIdLong.class, simpleObject).prop();
+
+            // then
+            assertThat(id).isGreaterThanOrEqualTo(0);
+        }
+    }
+
+    public static class DataNucleusVersionTimestamp extends SimpleObject_IntegTest {
+
+        @Test
+        public void should_be_populated() {
+            // when
+            final Timestamp timestamp = mixin(Persistable_datanucleusVersionTimestamp.class, simpleObject).prop();
+            // then
+            assertThat(timestamp).isNotNull();
+        }
+    }
 
 }
\ No newline at end of file
diff --git a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjects_IntegTest.java b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjects_IntegTest.java
index eff19b6..440b9e9 100644
--- a/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjects_IntegTest.java
+++ b/examples/apps/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjects_IntegTest.java
@@ -26,103 +26,106 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.MatcherAssert;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.jupiter.api.Test;
+import org.springframework.transaction.annotation.Transactional;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
 import domainapp.modules.simple.dom.impl.SimpleObjects;
 import domainapp.modules.simple.fixture.SimpleObject_persona;
 import domainapp.modules.simple.integtests.SimpleModuleIntegTestAbstract;
 
+@Transactional
 public class SimpleObjects_IntegTest extends SimpleModuleIntegTestAbstract {
-  //FIXME[2112] needs migration
-//    @Inject
-//    SimpleObjects menu;
-//
-//    public static class ListAll extends SimpleObjects_IntegTest {
-//
-//        @Test
-//        public void happyCase() {
-//
-//            // given
-//            fixtureScripts.runFixtureScript(new SimpleObject_persona.PersistAll());
-//            transactionService.nextTransaction();
-//
-//            // when
-//            final List<SimpleObject> all = wrap(menu).listAll();
-//
-//            // then
-//            assertThat(all).hasSize(SimpleObject_persona.values().length);
-//        }
-//
-//        @Test
-//        public void whenNone() {
-//
-//            // when
-//            final List<SimpleObject> all = wrap(menu).listAll();
-//
-//            // then
-//            assertThat(all).hasSize(0);
-//        }
-//    }
-//
-//    public static class Create extends SimpleObjects_IntegTest {
-//
-//        @Test
-//        public void happyCase() {
-//
-//            wrap(menu).create("Faz");
-//
-//            // then
-//            final List<SimpleObject> all = wrap(menu).listAll();
-//            assertThat(all).hasSize(1);
-//        }
-//
-//        @Test
-//        public void whenAlreadyExists() {
-//
-//            // given
-//            fixtureScripts.runBuilderScript(SimpleObject_persona.FIZZ.builder());
-//            transactionService.nextTransaction();
-//
-//            // expect
-//        	Throwable cause = assertThrows(Throwable.class, ()->{
-//            
-//                // when
-//                wrap(menu).create("Fizz");
-//                transactionService.nextTransaction();
-//            	
-//            });
-//        	
-//        	// also expect
-//        	MatcherAssert.assertThat(cause, 
-//        			causalChainContains(SQLIntegrityConstraintViolationException.class));
-//
-//        }
-//
-//        private static Matcher<Throwable> causalChainContains(final Class<?> cls) {
-//            return new TypeSafeMatcher<Throwable>() {
-//                @Override
-//                protected boolean matchesSafely(Throwable item) {
-//                    final List<Throwable> causalChain = Throwables.getCausalChain(item);
-//                    for (Throwable throwable : causalChain) {
-//                        if(cls.isAssignableFrom(throwable.getClass())){
-//                            return true;
-//                        }
-//                    }
-//                    return false;
-//                }
-//
-//                //@Override
-//                public void describeTo(Description description) {
-//                    description.appendText("exception with causal chain containing " + cls.getSimpleName());
-//                }
-//            };
-//        }
-//    }
+
+    @Inject
+    SimpleObjects menu;
+
+    public static class ListAll extends SimpleObjects_IntegTest {
+
+        @Test
+        public void happyCase() {
+
+            // given
+            fixtureScripts.runFixtureScript(new SimpleObject_persona.PersistAll());
+            transactionService.nextTransaction();
+
+            // when
+            final List<SimpleObject> all = wrap(menu).listAll();
+
+            // then
+            assertThat(all).hasSize(SimpleObject_persona.values().length);
+        }
+
+        @Test
+        public void whenNone() {
+
+            // when
+            final List<SimpleObject> all = wrap(menu).listAll();
+
+            // then
+            assertThat(all).hasSize(0);
+        }
+    }
+
+    public static class Create extends SimpleObjects_IntegTest {
+
+        @Test
+        public void happyCase() {
+
+            wrap(menu).create("Faz");
+
+            // then
+            final List<SimpleObject> all = wrap(menu).listAll();
+            assertThat(all).hasSize(1);
+        }
+
+        @Test
+        public void whenAlreadyExists() {
+
+            // given
+            fixtureScripts.runBuilderScript(SimpleObject_persona.FIZZ.builder());
+            transactionService.nextTransaction();
+
+            // expect
+        	Throwable cause = assertThrows(Throwable.class, ()->{
+            
+                // when
+                wrap(menu).create("Fizz");
+                transactionService.nextTransaction();
+            	
+            });
+        	
+        	// also expect
+        	MatcherAssert.assertThat(cause, 
+        			causalChainContains(SQLIntegrityConstraintViolationException.class));
+
+        }
+
+        private static Matcher<Throwable> causalChainContains(final Class<?> cls) {
+            return new TypeSafeMatcher<Throwable>() {
+                @Override
+                protected boolean matchesSafely(Throwable item) {
+                    final List<Throwable> causalChain = _Exceptions.getCausalChain(item);
+                    for (Throwable throwable : causalChain) {
+                        if(cls.isAssignableFrom(throwable.getClass())){
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+
+                //@Override
+                public void describeTo(Description description) {
+                    description.appendText("exception with causal chain containing " + cls.getSimpleName());
+                }
+            };
+        }
+    }
 
 
 }
\ No newline at end of file
diff --git a/extensions/fixtures/pom.xml b/extensions/fixtures/pom.xml
index 9e9f2e0..ec1a4c4 100644
--- a/extensions/fixtures/pom.xml
+++ b/extensions/fixtures/pom.xml
@@ -43,6 +43,12 @@
 
 		<dependency>
 			<groupId>org.apache.isis.core</groupId>
+			<artifactId>isis-integtestsupport</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.isis.core</groupId>
 			<artifactId>isis-runtime</artifactId>
 			<scope>provided</scope>
 		</dependency>
diff --git a/extensions/specsupport/src/main/java/org/apache/isis/runtime/headless/HeadlessAbstract.java b/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/IsisIntegrationTestAbstactWithFixtures.java
similarity index 53%
rename from extensions/specsupport/src/main/java/org/apache/isis/runtime/headless/HeadlessAbstract.java
rename to extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/IsisIntegrationTestAbstactWithFixtures.java
index ffb62e95..cc11431 100644
--- a/extensions/specsupport/src/main/java/org/apache/isis/runtime/headless/HeadlessAbstract.java
+++ b/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/IsisIntegrationTestAbstactWithFixtures.java
@@ -16,38 +16,22 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.runtime.headless;
+package org.apache.isis.extensions.fixtures;
 
 import javax.inject.Inject;
 
-import org.joda.time.LocalDate;
-
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.applib.services.factory.FactoryService;
-import org.apache.isis.applib.services.metamodel.MetaModelService;
-import org.apache.isis.applib.services.registry.ServiceRegistry;
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.applib.services.sessmgmt.SessionManagementService;
-import org.apache.isis.applib.services.user.UserService;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.extensions.fixtures.api.PersonaWithBuilderScript;
 import org.apache.isis.extensions.fixtures.legacy.FixtureClock;
 import org.apache.isis.extensions.fixtures.legacy.TickingFixtureClock;
 import org.apache.isis.extensions.fixtures.legacy.fixturescripts.BuilderScriptAbstract;
 import org.apache.isis.extensions.fixtures.legacy.fixturescripts.FixtureScript;
 import org.apache.isis.extensions.fixtures.legacy.fixturescripts.FixtureScripts;
+import org.apache.isis.integtestsupport.IsisIntegrationTestAbstact;
+import org.joda.time.LocalDate;
 
-/**
- * Reworked base class for headless access.
- *
- * <p>
- *     The most common cases are integration tests or BDD spec glue.
- * </p>
- */
-public abstract class HeadlessAbstract {
-
+public abstract class IsisIntegrationTestAbstactWithFixtures extends IsisIntegrationTestAbstact {
 
     protected void runFixtureScript(final FixtureScript... fixtureScriptList) {
         this.fixtureScripts.runFixtureScript(fixtureScriptList);
@@ -62,50 +46,6 @@ public abstract class HeadlessAbstract {
         return runBuilderScript(builderScript);
     }
 
-
-    /**
-     * Convenience method, simply delegates to {@link WrapperFactory#wrap(Object)}
-     */
-    protected <T> T wrap(final T obj) {
-        return wrapperFactory.wrap(obj);
-    }
-
-    /**
-     * Convenience method, synonym of {@link #wrap(Object)}
-     */
-    protected <T> T w(final T obj) {
-        return wrap(obj);
-    }
-
-    /**
-     * Convenience method, simply delegates to {@link WrapperFactory#wrapMixin(Class, Object)}.
-     */
-    protected <T> T wrapMixin(final Class<T> mixinClass, final Object mixedIn) {
-        return wrapperFactory.wrapMixin(mixinClass, mixedIn);
-    }
-
-    /**
-     * Convenience method, synonym for {@link #wrapMixin(Class, Object)}.
-     */
-    protected <T> T wm(final Class<T> mixinClass, final Object mixedIn) {
-        return wrapMixin(mixinClass, mixedIn);
-    }
-
-    /**
-     * Convenience method, simply delegates to {@link FactoryService#mixin(Class, Object)}.
-     */
-    protected <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
-        return factoryService.mixin(mixinClass, mixedIn);
-    }
-
-    /**
-     * Convenience method, synonym for {@link #mixin(Class, Object)}.
-     */
-    protected <T> T m(final Class<T> mixinClass, final Object mixedIn) {
-        return factoryService.m(mixinClass, mixedIn);
-    }
-
-
     /**
      * To use instead of {@link #getFixtureClock()}'s {@link FixtureClock#setDate(int, int, int)} ()}.
      */
@@ -140,31 +80,9 @@ public abstract class HeadlessAbstract {
         return ((FixtureClock)FixtureClock.getInstance());
     }
 
+    // -- DEPENDENCIES
 
-    /**
-     * For convenience of subclasses, remove some boilerplate
-     */
-    protected <T> T unwrap(final T obj) {
-        return wrapperFactory.unwrap(obj);
-    }
-
-    @Inject
-    protected MetaModelService metaModelService;
-    @Inject
-    protected FixtureScripts fixtureScripts;
-    @Inject
-    protected FactoryService factoryService;
-    @Inject
-    protected ServiceRegistry serviceRegistry;
-    @Inject
-    protected RepositoryService repositoryService;
-    @Inject
-    protected UserService userService;
-    @Inject
-    protected WrapperFactory wrapperFactory;
-    @Inject
-    protected TransactionService transactionService;
-    @Inject
-    protected SessionManagementService sessionManagementService;
+    @Inject protected FixtureScripts fixtureScripts;
 
-}
\ No newline at end of file
+	
+}