diff --git a/kickstartWithBootstrap/KickstartWithBootstrapGrailsPlugin.groovy b/kickstartWithBootstrap/KickstartWithBootstrapGrailsPlugin.groovy index 3c25b0c..6ba161c 100644 --- a/kickstartWithBootstrap/KickstartWithBootstrapGrailsPlugin.groovy +++ b/kickstartWithBootstrap/KickstartWithBootstrapGrailsPlugin.groovy @@ -1,6 +1,6 @@ class KickstartWithBootstrapGrailsPlugin { // the plugin version - def version = "0.8.1" + def version = "0.8.3" // the version or versions of Grails the plugin is designed for def grailsVersion = "2.0.0 > *" // the other plugins this plugin depends on diff --git a/kickstartWithBootstrap/README.mediawiki b/kickstartWithBootstrap/README.mediawiki index e7ec071..d9fe19e 100644 --- a/kickstartWithBootstrap/README.mediawiki +++ b/kickstartWithBootstrap/README.mediawiki @@ -39,12 +39,6 @@ Affected files and directories (as of version 0.8.0; see script/Kickstart.groovy * /views/index.gsp will be '''deleted'''! * /views/error.gsp will be '''deleted'''! -== Rare Problems == -During development and testing several strange error have emerged (they might be problems caused by the G&G Tool Suite - a restart of the GGTS helped me): - -* Sometimes the conf/URLmappings.groovy file is not copied by the Kickstart script into the conf directory of your project. If you run-app your project and get a 404 regarding the page "/WEB-INF/grails-app/views/index.jsp" you have to copy it yourself manually. -* Sometimes the I18N files from the Kickstart plugin are not used. If you see I18N-codes such as "default.welcome.title" you have to copy the content of the I18N files into the property files in your project. - == Terms of Use == * Web Layout: [http://twitter.github.com/bootstrap/ Bootstrap 2.1], from Twitter Licensed under the Apache License v2.0. Documentation licensed under CC BY 3.0. (@TwBootstrap , http://twitter.github.com/bootstrap/) @@ -56,6 +50,10 @@ During development and testing several strange error have emerged (they might be == Changelog == +;0.8.3 +: Introduced a demo page with all fields used in the scaffolding process. +;0.8.2 +: Corrected missing copy of resources.groovy. ;0.8.1 : Fixed error when copying UrlMappings.groovy, which was not packaged into the plugin. ;0.8.0 diff --git a/kickstartWithBootstrap/application.properties b/kickstartWithBootstrap/application.properties index 51c894d..aee700a 100644 --- a/kickstartWithBootstrap/application.properties +++ b/kickstartWithBootstrap/application.properties @@ -1,26 +1,26 @@ #Grails Metadata file -#Tue Oct 23 21:16:12 CEST 2012 +#Sat Oct 27 20:08:39 CEST 2012 app.grails.version=2.1.1 app.name=kickstartWithBootstrapGrailsPlugin app.stats.Controllers.files=2 app.stats.Controllers.loc=90 app.stats.Domain_Classes.files=1 -app.stats.Domain_Classes.loc=12 +app.stats.Domain_Classes.loc=47 app.stats.Groovy_Helpers.files=1 app.stats.Groovy_Helpers.loc=10 app.stats.Scripts.files=5 -app.stats.Scripts.loc=122 +app.stats.Scripts.loc=134 app.stats.Tag_Libraries.files=1 app.stats.Tag_Libraries.loc=279 app.stats.Totals.files=12 -app.stats.Totals.loc=623 +app.stats.Totals.loc=670 app.stats.Unit_Tests.files=2 app.stats.Unit_Tests.loc=110 -app.version=0.8.1 -app.version.build=123 -app.version.build.date=Okt 23, 2012 +app.version=0.8.3 +app.version.build=150 +app.version.build.date=Okt 27, 2012 app.version.build.env=development -app.version.revision=c59697e +app.version.revision=ada1626 plugins.hibernate=2.1.1 plugins.jquery=1.8.0 plugins.lesscss-resources=1.3.0.3 diff --git a/kickstartWithBootstrap/grails-app/controllers/kickstartwithbootstrapgrailsplugin/_DemoPageController.groovy b/kickstartWithBootstrap/grails-app/controllers/kickstartwithbootstrapgrailsplugin/_DemoPageController.groovy new file mode 100644 index 0000000..b9d00fc --- /dev/null +++ b/kickstartWithBootstrap/grails-app/controllers/kickstartwithbootstrapgrailsplugin/_DemoPageController.groovy @@ -0,0 +1,107 @@ +package kickstartwithbootstrapgrailsplugin + +import org.springframework.dao.DataIntegrityViolationException + +/** + * _DemoPageController + * A controller class handles incoming web requests and performs actions such as redirects, rendering views and so on. + */ +class _DemoPageController { + + static allowedMethods = [save: "POST", update: "POST", delete: "POST"] + + def index() { + redirect(action: "list", params: params) + } + + def list() { + params.max = Math.min(params.max ? params.int('max') : 10, 100) + [_DemoPageInstanceList: _DemoPage.list(params), _DemoPageInstanceTotal: _DemoPage.count()] + } + + def create() { + [_DemoPageInstance: new _DemoPage(params)] + } + + def save() { + def _DemoPageInstance = new _DemoPage(params) + if (!_DemoPageInstance.save(flush: true)) { + render(view: "create", model: [_DemoPageInstance: _DemoPageInstance]) + return + } + + flash.message = message(code: 'default.created.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), _DemoPageInstance.id]) + redirect(action: "show", id: _DemoPageInstance.id) + } + + def show() { + def _DemoPageInstance = _DemoPage.get(params.id) + if (!_DemoPageInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "list") + return + } + + [_DemoPageInstance: _DemoPageInstance] + } + + def edit() { + def _DemoPageInstance = _DemoPage.get(params.id) + if (!_DemoPageInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "list") + return + } + + [_DemoPageInstance: _DemoPageInstance] + } + + def update() { + def _DemoPageInstance = _DemoPage.get(params.id) + if (!_DemoPageInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "list") + return + } + + if (params.version) { + def version = params.version.toLong() + if (_DemoPageInstance.version > version) { + _DemoPageInstance.errors.rejectValue("version", "default.optimistic.locking.failure", + [message(code: '_DemoPage.label', default: '_DemoPage')] as Object[], + "Another user has updated this _DemoPage while you were editing") + render(view: "edit", model: [_DemoPageInstance: _DemoPageInstance]) + return + } + } + + _DemoPageInstance.properties = params + + if (!_DemoPageInstance.save(flush: true)) { + render(view: "edit", model: [_DemoPageInstance: _DemoPageInstance]) + return + } + + flash.message = message(code: 'default.updated.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), _DemoPageInstance.id]) + redirect(action: "show", id: _DemoPageInstance.id) + } + + def delete() { + def _DemoPageInstance = _DemoPage.get(params.id) + if (!_DemoPageInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "list") + return + } + + try { + _DemoPageInstance.delete(flush: true) + flash.message = message(code: 'default.deleted.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "list") + } + catch (DataIntegrityViolationException e) { + flash.message = message(code: 'default.not.deleted.message', args: [message(code: '_DemoPage.label', default: '_DemoPage'), params.id]) + redirect(action: "show", id: params.id) + } + } +} diff --git a/kickstartWithBootstrap/grails-app/domain/kickstartwithbootstrapgrailsplugin/_DemoPage.groovy b/kickstartWithBootstrap/grails-app/domain/kickstartwithbootstrapgrailsplugin/_DemoPage.groovy new file mode 100644 index 0000000..834ec0e --- /dev/null +++ b/kickstartWithBootstrap/grails-app/domain/kickstartwithbootstrapgrailsplugin/_DemoPage.groovy @@ -0,0 +1,84 @@ +package kickstartwithbootstrapgrailsplugin + +/** + * _DemoPage + * A domain class describes the data object and it's mapping to the database + */ +class _DemoPage { + + /* Default (injected) attributes of GORM */ +// Long id +// String version + + String name = "The Demo Page" + + // fields with special use (e.g., datepicker, new visual representation, etc.) + Date myDate + boolean myBoolean + + // other fields used in the scaffolding process: + int myInt + short myShort + long myLong + float myFloat + double myDouble + byte myByte + char myChar + + byte[] myByteArray +// char[] myCharArray // Grails original URL scaffolding seems to have problems + +// URL myURL // Grails original URL scaffolding seems to have problems + Integer myInteger + TimeZone myTimeZone + Locale myLocale + Currency myCurrency + + public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } + Suit myEnum + + /* Automatic timestamping of GORM */ + Date dateCreated + Date lastUpdated + +// static belongsTo = [] // tells GORM to cascade commands: e.g., delete this object if the "parent" is deleted. +// static hasOne = [] // tells GORM to associate another domain object as an owner in a 1-1 mapping +// static hasMany = [] // tells GORM to associate other domain objects for a 1-n or n-m mapping +// static mappedBy = [] // specifies which property should be used in a mapping + + static mapping = { + } + + static constraints = { + // make all fields nullable to speed up demo usage (e.g., saves) + name nullable: true + + myDate nullable: true + myBoolean nullable: true + + myInt nullable: true + myShort nullable: true + myLong nullable: true + myFloat nullable: true + myDouble nullable: true + myByte nullable: true + myChar nullable: true + + myByteArray nullable: true +// myCharArray nullable: true + +// myURL nullable: true + myInteger nullable: true + myTimeZone nullable: true + myLocale nullable: true + myCurrency nullable: true + } + + /* + * Methods of the Domain Class + */ + @Override // Override toString for a nicer / more descriptive UI + public String toString() { + return "${name}"; + } +} diff --git a/kickstartWithBootstrap/grails-app/i18n/messages.properties b/kickstartWithBootstrap/grails-app/i18n/messages.properties index 9e55d6a..386f8c1 100644 --- a/kickstartWithBootstrap/grails-app/i18n/messages.properties +++ b/kickstartWithBootstrap/grails-app/i18n/messages.properties @@ -64,3 +64,5 @@ security.signoff.label = Sign out checkbox.on.label = On checkbox.off.label = Off + +default.date.format = yyyy-MM-dd \ No newline at end of file diff --git a/kickstartWithBootstrap/grails-app/i18n/messages_de.properties b/kickstartWithBootstrap/grails-app/i18n/messages_de.properties index dfbcd91..e414f30 100644 --- a/kickstartWithBootstrap/grails-app/i18n/messages_de.properties +++ b/kickstartWithBootstrap/grails-app/i18n/messages_de.properties @@ -63,3 +63,5 @@ security.signoff.label = Ausloggen checkbox.on.label = An checkbox.off.label = Aus + +default.date.format = dd. MM. yyyy diff --git a/kickstartWithBootstrap/grails-app/views/_DemoPage/_form.gsp b/kickstartWithBootstrap/grails-app/views/_DemoPage/_form.gsp new file mode 100644 index 0000000..4ca8830 --- /dev/null +++ b/kickstartWithBootstrap/grails-app/views/_DemoPage/_form.gsp @@ -0,0 +1,132 @@ +<%@ page import="kickstartwithbootstrapgrailsplugin._DemoPage" %> + + + +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'name', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myDate', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myBoolean', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myInt', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myShort', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myLong', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myFloat', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myDouble', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myByte', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myChar', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myByteArray', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myInteger', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myTimeZone', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myLocale', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myCurrency', 'error')} +
+
+ +
+ +
+ + ${hasErrors(bean: _DemoPageInstance, field: 'myEnum', 'error')} +
+
+ diff --git a/kickstartWithBootstrap/grails-app/views/test/create.gsp b/kickstartWithBootstrap/grails-app/views/_DemoPage/create.gsp similarity index 62% rename from kickstartWithBootstrap/grails-app/views/test/create.gsp rename to kickstartWithBootstrap/grails-app/views/_DemoPage/create.gsp index ae3221d..281e502 100644 --- a/kickstartWithBootstrap/grails-app/views/test/create.gsp +++ b/kickstartWithBootstrap/grails-app/views/_DemoPage/create.gsp @@ -1,25 +1,25 @@ -<%@ page import="kickstartwithbootstrapgrailsplugin.Test" %> +<%@ page import="kickstartwithbootstrapgrailsplugin._DemoPage" %> - + <g:message code="default.create.label" args="[entityName]" /> -
+
- +
- +
- +
diff --git a/kickstartWithBootstrap/grails-app/views/test/edit.gsp b/kickstartWithBootstrap/grails-app/views/_DemoPage/edit.gsp similarity index 63% rename from kickstartWithBootstrap/grails-app/views/test/edit.gsp rename to kickstartWithBootstrap/grails-app/views/_DemoPage/edit.gsp index 78b1046..3509251 100644 --- a/kickstartWithBootstrap/grails-app/views/test/edit.gsp +++ b/kickstartWithBootstrap/grails-app/views/_DemoPage/edit.gsp @@ -1,27 +1,27 @@ -<%@ page import="kickstartwithbootstrapgrailsplugin.Test" %> +<%@ page import="kickstartwithbootstrapgrailsplugin._DemoPage" %> - + <g:message code="default.edit.label" args="[entityName]" /> -
+
- +
- +
- - - + + +
diff --git a/kickstartWithBootstrap/grails-app/views/_DemoPage/list.gsp b/kickstartWithBootstrap/grails-app/views/_DemoPage/list.gsp new file mode 100644 index 0000000..a86d2ce --- /dev/null +++ b/kickstartWithBootstrap/grails-app/views/_DemoPage/list.gsp @@ -0,0 +1,61 @@ + +<%@ page import="kickstartwithbootstrapgrailsplugin._DemoPage" %> + + + + + + + <g:message code="default.list.label" args="[entityName]" /> + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${fieldValue(bean: _DemoPageInstance, field: "name")}${fieldValue(bean: _DemoPageInstance, field: "myInt")}${fieldValue(bean: _DemoPageInstance, field: "myShort")}${fieldValue(bean: _DemoPageInstance, field: "myLong")}
+ +
+ + + + diff --git a/kickstartWithBootstrap/grails-app/views/_DemoPage/show.gsp b/kickstartWithBootstrap/grails-app/views/_DemoPage/show.gsp new file mode 100644 index 0000000..7ca29dc --- /dev/null +++ b/kickstartWithBootstrap/grails-app/views/_DemoPage/show.gsp @@ -0,0 +1,150 @@ + +<%@ page import="kickstartwithbootstrapgrailsplugin._DemoPage" %> + + + + + + + + <g:message code="default.show.label" args="[entityName]" /> + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${fieldValue(bean: _DemoPageInstance, field: "name")}
${fieldValue(bean: _DemoPageInstance, field: "myInt")}
${fieldValue(bean: _DemoPageInstance, field: "myShort")}
${fieldValue(bean: _DemoPageInstance, field: "myLong")}
${fieldValue(bean: _DemoPageInstance, field: "myFloat")}
${fieldValue(bean: _DemoPageInstance, field: "myDouble")}
${fieldValue(bean: _DemoPageInstance, field: "myByte")}
${fieldValue(bean: _DemoPageInstance, field: "myChar")}
${fieldValue(bean: _DemoPageInstance, field: "myInteger")}
${fieldValue(bean: _DemoPageInstance, field: "myTimeZone")}
${fieldValue(bean: _DemoPageInstance, field: "myLocale")}
${fieldValue(bean: _DemoPageInstance, field: "myCurrency")}
${_DemoPageInstance?.myEnum?.encodeAsHTML()}
+
+ + + + diff --git a/kickstartWithBootstrap/grails-app/views/test/_form.gsp b/kickstartWithBootstrap/grails-app/views/test/_form.gsp deleted file mode 100644 index f4dd430..0000000 --- a/kickstartWithBootstrap/grails-app/views/test/_form.gsp +++ /dev/null @@ -1,27 +0,0 @@ -<%@ page import="kickstartwithbootstrapgrailsplugin.Test" %> - - -
- -
- - ${hasErrors(bean: testInstance, field: 'isGrailsUser', 'error')} -
-
- -
- -
- - ${hasErrors(bean: testInstance, field: 'birthday', 'error')} -
-
- -
- -
- - ${hasErrors(bean: testInstance, field: 'name', 'error')} -
-
- diff --git a/kickstartWithBootstrap/grails-app/views/test/list.gsp b/kickstartWithBootstrap/grails-app/views/test/list.gsp deleted file mode 100644 index 82d8406..0000000 --- a/kickstartWithBootstrap/grails-app/views/test/list.gsp +++ /dev/null @@ -1,49 +0,0 @@ - -<%@ page import="kickstartwithbootstrapgrailsplugin.Test" %> - - - - - - - <g:message code="default.list.label" args="[entityName]" /> - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
${fieldValue(bean: testInstance, field: "birthday")}${fieldValue(bean: testInstance, field: "name")}
- -
- - - - diff --git a/kickstartWithBootstrap/grails-app/views/test/show.gsp b/kickstartWithBootstrap/grails-app/views/test/show.gsp deleted file mode 100644 index bb9dcc7..0000000 --- a/kickstartWithBootstrap/grails-app/views/test/show.gsp +++ /dev/null @@ -1,47 +0,0 @@ - -<%@ page import="kickstartwithbootstrapgrailsplugin.Test" %> - - - - - - - - <g:message code="default.show.label" args="[entityName]" /> - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
${fieldValue(bean: testInstance, field: "name")}
-
- - - - diff --git a/kickstartWithBootstrap/plugin.xml b/kickstartWithBootstrap/plugin.xml index 5cceaa9..605db3c 100644 --- a/kickstartWithBootstrap/plugin.xml +++ b/kickstartWithBootstrap/plugin.xml @@ -1,4 +1,4 @@ - + Joerg Rech joerg.rech@gmail.com Kickstart with Bootstrap - Good looking websites! @@ -10,8 +10,8 @@ kickstart.KickstartFilters spring.resources HomeController - kickstartwithbootstrapgrailsplugin.TestController - kickstartwithbootstrapgrailsplugin.Test + kickstartwithbootstrapgrailsplugin._DemoPageController + kickstartwithbootstrapgrailsplugin._DemoPage kickstart.BootstrapTagLib diff --git a/kickstartWithBootstrap/scripts/Kickstart.groovy b/kickstartWithBootstrap/scripts/Kickstart.groovy index c48ded2..7d0cec7 100644 --- a/kickstartWithBootstrap/scripts/Kickstart.groovy +++ b/kickstartWithBootstrap/scripts/Kickstart.groovy @@ -14,12 +14,13 @@ def deleteAll = false target(kickstart: "Installs the Kickstart scaffolding templates and other files") { depends(checkVersion, parseArguments) - event "StatusUpdate", ['\nNOTE: execution in eclipse (STS, GGTS) might result in the erroneous messages "Invalid input. Must be one of"! Just ignore them!\n'] + event "StatusUpdate", ['\nNOTE: execution in eclipse (STS, GGTS) might result in the erroneous messages "Invalid input. Must be one of" --> Just ignore them!\n'] sourceDir = "${kickstartWithBootstrapPluginDir}/src" targetDir = "${basedir}/grails-app/conf/" - copy("${sourceDir}/UrlMappings.groovy", targetDir, "URLMappings.groovy", code) - + copy("${sourceDir}/UrlMappings.groovy", targetDir, "URLMappings.groovy", code) + copy("${sourceDir}/resources.groovy", targetDir+"spring/","resources.groovy", code) + // copy less files into project sourceDir = "${kickstartWithBootstrapPluginDir}/web-app/less" targetDir = "${basedir}/web-app/less" diff --git a/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageControllerTests.groovy b/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageControllerTests.groovy new file mode 100644 index 0000000..83dc003 --- /dev/null +++ b/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageControllerTests.groovy @@ -0,0 +1,163 @@ +package kickstartwithbootstrapgrailsplugin + + + +import org.junit.* +import grails.test.mixin.* + +/** + * _DemoPageControllerTests + * A unit test class is used to test individual methods or blocks of code without considering the surrounding infrastructure + */ +@TestFor(_DemoPageController) +@Mock(_DemoPage) +class _DemoPageControllerTests { + + + def populateValidParams(params) { + assert params != null + // TODO: Populate valid properties like... + //params["name"] = 'someValidName' + } + + void testIndex() { + controller.index() + assert "/_DemoPage/list" == response.redirectedUrl + } + + void testList() { + + def model = controller.list() + + assert model._DemoPageInstanceList.size() == 0 + assert model._DemoPageInstanceTotal == 0 + } + + void testCreate() { + def model = controller.create() + + assert model._DemoPageInstance != null + } + + void testSave() { + controller.save() + + assert model._DemoPageInstance != null + assert view == '/_DemoPage/create' + + response.reset() + + populateValidParams(params) + controller.save() + + assert response.redirectedUrl == '/_DemoPage/show/1' + assert controller.flash.message != null + assert _DemoPage.count() == 1 + } + + void testShow() { + controller.show() + + assert flash.message != null + assert response.redirectedUrl == '/_DemoPage/list' + + + populateValidParams(params) + def _DemoPage = new _DemoPage(params) + + assert _DemoPage.save() != null + + params.id = _DemoPage.id + + def model = controller.show() + + assert model._DemoPageInstance == _DemoPage + } + + void testEdit() { + controller.edit() + + assert flash.message != null + assert response.redirectedUrl == '/_DemoPage/list' + + + populateValidParams(params) + def _DemoPage = new _DemoPage(params) + + assert _DemoPage.save() != null + + params.id = _DemoPage.id + + def model = controller.edit() + + assert model._DemoPageInstance == _DemoPage + } + + void testUpdate() { + controller.update() + + assert flash.message != null + assert response.redirectedUrl == '/_DemoPage/list' + + response.reset() + + + populateValidParams(params) + def _DemoPage = new _DemoPage(params) + + assert _DemoPage.save() != null + + // test invalid parameters in update + params.id = _DemoPage.id + //TODO: add invalid values to params object + + controller.update() + + assert view == "/_DemoPage/edit" + assert model._DemoPageInstance != null + + _DemoPage.clearErrors() + + populateValidParams(params) + controller.update() + + assert response.redirectedUrl == "/_DemoPage/show/$_DemoPage.id" + assert flash.message != null + + //test outdated version number + response.reset() + _DemoPage.clearErrors() + + populateValidParams(params) + params.id = _DemoPage.id + params.version = -1 + controller.update() + + assert view == "/_DemoPage/edit" + assert model._DemoPageInstance != null + assert model._DemoPageInstance.errors.getFieldError('version') + assert flash.message != null + } + + void testDelete() { + controller.delete() + assert flash.message != null + assert response.redirectedUrl == '/_DemoPage/list' + + response.reset() + + populateValidParams(params) + def _DemoPage = new _DemoPage(params) + + assert _DemoPage.save() != null + assert _DemoPage.count() == 1 + + params.id = _DemoPage.id + + controller.delete() + + assert _DemoPage.count() == 0 + assert _DemoPage.get(_DemoPage.id) == null + assert response.redirectedUrl == '/_DemoPage/list' + } +} diff --git a/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageTests.groovy b/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageTests.groovy new file mode 100644 index 0000000..1a6d003 --- /dev/null +++ b/kickstartWithBootstrap/test/unit/kickstartwithbootstrapgrailsplugin/_DemoPageTests.groovy @@ -0,0 +1,17 @@ +package kickstartwithbootstrapgrailsplugin + + + +import grails.test.mixin.* +import org.junit.* + +/** + * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions + */ +@TestFor(_DemoPage) +class _DemoPageTests { + + void testSomething() { + fail "Implement me" + } +}