001    /**
002     * Copyright 2004-2014 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.student.mock.mojo;
017    
018    import org.kuali.student.contract.model.MessageStructure;
019    import org.kuali.student.contract.model.Service;
020    import org.kuali.student.contract.model.ServiceContractModel;
021    import org.kuali.student.contract.model.ServiceMethod;
022    import org.kuali.student.contract.model.ServiceMethodError;
023    import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
024    
025    import java.util.List;
026    
027    /**
028     * This class will generate the extended class that does CRUD tests as
029     * part of the Conformance Tests for services. The generated class will
030     * complete the base class and is meant to be generated once and then
031     * edited (and mantained) by developers.
032     *
033     * @author Mezba Mahtab (mezba.mahtab@utoronto.ca)
034     */
035    public class ConformanceTestExtendedCrudClassServiceWriter extends ConformanceTestBaseCrudClassServiceWriter {
036    
037        ////////////////////////////
038        // CONSTRUCTOR
039        ////////////////////////////
040    
041        public ConformanceTestExtendedCrudClassServiceWriter (ServiceContractModel model,
042                                                              String directory,
043                                                              String rootPackage,
044                                                              String servKey,
045                                                              List<ServiceMethod> methods,
046                                                              boolean isR1) {
047            super(model, directory, rootPackage, servKey, methods, isR1, calcPackage(servKey, rootPackage), calcClassName(servKey));
048        }
049    
050        //////////////////////////
051        // FUNCTIONALS
052        //////////////////////////
053    
054        /**
055         * Given the service key (name), returns a calculated class name for the conformance tester.
056         */
057        public static String calcClassName(String servKey) {
058            return "Test" + GetterSetterNameCalculator.calcInitUpper(fixServKey(servKey) + "ServiceImplConformanceExtendedCrud");
059        }
060    
061        /**
062         * Write out the entire file
063         */
064        public void write() {
065            // begin file
066            indentPrintln("@RunWith(SpringJUnit4ClassRunner.class)");
067            indentPrintln("@ContextConfiguration(locations = {\"classpath:" + servKey + "-test-with-mock-context.xml\"})");
068            indentPrint("public class " + calcClassName(servKey));
069            println(" extends " + super.calcClassName(servKey) + " ");
070            Service serv = finder.findService(servKey);
071            setPackageName(serv.getImplProject() + ".impl"); // change the package name
072            importsAdd(serv.getImplProject() + "." + serv.getName()); // import for the service
073            doTestImportsAdd();
074            openBrace();
075    
076            indentPrintln("");
077    
078            // print out list of methods for DTO fields per DTO that need to be completed
079            indentPrintDecoratedComment("DTO FIELD SPECIFIC METHODS", H1_COMMENT_CHAR, H1_COMMENT_MARK_LENGTH*2);
080            indentPrintln("");
081    
082            // for each DTO, write the DOT field management methods that were left abstract in base class
083            for (String dtoObjectName : calcNamesOfDTOsWithCrudManagedByService()) {
084                indentPrintln("// ****************************************************");
085                indentPrintln("//           " + dtoObjectName + "Info");
086                indentPrintln("// ****************************************************");
087                indentPrintln("");
088    
089                // get the message structures of the dto
090                List<MessageStructure> messageStructures = finder.findMessageStructures(dtoObjectName + "Info");
091    
092                writetestCrudXXX_setDTOFieldsForTestCreate(dtoObjectName, messageStructures);
093                writetestCrudXXX_testDTOFieldsForTestCreateUpdate(dtoObjectName, messageStructures);
094                writetestCrudXXX_setDTOFieldsForTestUpdate(dtoObjectName, messageStructures);
095                writetestCrudXXX_testDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
096                writetestCrudXXX_setDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
097                indentPrintln("");
098            }
099    
100            // print out list of service operations that are not tested as abstract test methods
101            indentPrintDecoratedComment("SERVICE OPS NOT TESTED IN BASE TEST CLASS", H1_COMMENT_CHAR, H1_COMMENT_MARK_LENGTH*2);
102            indentPrintln("");
103    
104            // for each method, create an abstract method to test that and print it out
105            for (ServiceMethod method: methods) {
106                if (!isServiceMethodTestedAsPartofCrudInBaseConformanceTest (method)) {
107                    indentPrintln("/* Method Name: " + method.getName() + " */");
108                    indentPrintln("@Test");
109                    indentPrintln("public void test_" + method.getName() + "() ");
110                    if (method.getErrors().size()>0) {
111                        indentPrint("throws ");
112                        String comma = "";
113                        for (ServiceMethodError error: method.getErrors()) {
114                            indentPrint(comma + error.getClassName().trim());
115                            comma = ",";
116                        }
117                    }
118                    openBrace();
119                    closeBrace();
120                    indentPrintln("");
121                }
122            }
123    
124    
125    
126            // end file print out
127            closeBrace ();
128            println ("");
129    
130            // close and print file
131            this.writeJavaClassAndImportsOutToFile();
132            this.getOut().close();
133        }
134    
135        /**
136         * Writes the section to set fields specific to this dto for testCreate section.
137         */
138        public void writetestCrudXXX_setDTOFieldsForTestCreate(String dtoObjectName, List<MessageStructure> messageStructures) {
139            indentPrintln("/*");
140            incrementIndent();
141            indentPrintln("A method to set the fields for a " + dtoObjectName  + " in a 'test create' section prior to calling the 'create' operation.");
142            decrementIndent();
143            indentPrintln("*/");
144            indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestCreate(" + dtoObjectName + "Info expected) ");
145            openBrace();
146            for (MessageStructure ms: messageStructures) {
147                if (ms.getShortName().equals("id")) continue;
148                if (ms.getShortName().equals("meta")) continue;
149                if (ms.getShortName().equals("attributes")) continue;
150                if (ms.getType().equals("String")) {
151                    indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "01\");");
152                }
153                else if (ms.getShortName().equals("descr")) {
154                    indentPrintln("expected.setDescr(RichTextHelper.buildRichTextInfo(\"descr01\", \"descr01\"));");
155                }
156                else {
157                    indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "01\");");
158                }
159            }
160            closeBrace();
161            indentPrintln("");
162        }
163    
164        /**
165         * Writes the section to test fields specific to this dto for testCreate and testUpdate sections.
166         */
167        public void writetestCrudXXX_testDTOFieldsForTestCreateUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
168            indentPrintln("/*");
169            incrementIndent();
170            indentPrintln("A method to test the fields for a " + dtoObjectName  + ". This is called after:");
171            indentPrintln("- creating a DTO, where actual is the DTO returned by the create operation, and expected is the dto passed in to the create operation");
172            indentPrintln("- reading a DTO after creating it, and actual is the read DTO, and expected is the dto that was created");
173            indentPrintln("- updating a DTO, where actual is DTO returned by the update operation, and expected is the dto that was passed in to the update operation");
174            decrementIndent();
175            indentPrintln("*/");
176            indentPrintln("public void testCrud" + dtoObjectName + "_testDTOFieldsForTestCreateUpdate(" + dtoObjectName + "Info expected, " + dtoObjectName + "Info actual) ");
177            openBrace();
178            for (MessageStructure ms: messageStructures) {
179                if (ms.getShortName().equals("id")) continue;
180                if (ms.getShortName().equals("meta")) continue;
181                if (ms.getShortName().equals("attributes")) continue;
182                if (ms.getType().equals("String")) {
183                    indentPrintln("assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
184                }
185                else if (ms.getShortName().equals("descr")) {
186                    indentPrintln("new RichTextTester().check(expected.getDescr(), actual.getDescr());");
187                }
188                else {
189                    indentPrintln("//TODO *TYPE = " + ms.getType() + "* assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
190                }
191            }
192            closeBrace();
193            indentPrintln("");
194        }
195    
196    
197        /**
198         * Writes the section to set fields specific to this dto for testUpdate sections.
199         */
200        public void writetestCrudXXX_setDTOFieldsForTestUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
201            indentPrintln("/*");
202            incrementIndent();
203            indentPrintln("A method to set the fields for a " + dtoObjectName + " in a 'test update' section prior to calling the 'update' operation.");
204            decrementIndent();
205            indentPrintln("*/");
206            indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestUpdate(" + dtoObjectName + "Info expected) ");
207            openBrace();
208            for (MessageStructure ms: messageStructures) {
209                if (ms.getShortName().equals("id")) continue;
210                if (ms.getShortName().equals("meta")) continue;
211                if (ms.getShortName().equals("attributes")) continue;
212                if (ms.getType().equals("String")) {
213                    indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
214                }
215                else if (ms.getShortName().equals("descr")) {
216                    indentPrintln("expected.setDescr(RichTextHelper.buildRichTextInfo(\"descr_Updated\", \"descr_Updated\"));");
217                }
218                else {
219                    indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
220                }
221            }
222            closeBrace();
223            indentPrintln("");
224        }
225    
226        /**
227         * Writes the section to test fields specific to this dto for testReadAfterUpdate sections.
228         */
229        public void writetestCrudXXX_testDTOFieldsForTestReadAfterUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
230            indentPrintln("/*");
231            incrementIndent();
232            indentPrintln("A method to test the fields for a " + dtoObjectName  + " after an update operation, followed by a read operation,");
233            indentPrintln("where actual is the DTO returned by the read operation, and expected is the dto returned by the update operation.");
234            decrementIndent();
235            indentPrintln("*/");
236            indentPrintln("public void testCrud" + dtoObjectName + "_testDTOFieldsForTestReadAfterUpdate(" + dtoObjectName + "Info expected, " + dtoObjectName + "Info actual) ");
237            openBrace();
238            for (MessageStructure ms: messageStructures) {
239                if (ms.getShortName().equals("meta")) continue;
240                if (ms.getShortName().equals("attributes")) continue;
241                if (ms.getType().equals("String")) {
242                    indentPrintln("assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
243                }
244                else if (ms.getShortName().equals("descr")) {
245                    indentPrintln("new RichTextTester().check(expected.getDescr(), actual.getDescr());");
246                }
247                else {
248                    indentPrintln("//TODO *TYPE = " + ms.getType() + "* assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
249                }
250            }
251            closeBrace();
252            indentPrintln("");
253        }
254    
255        /**
256         * Writes the section to set fields specific to this dto for testReadAfterUpdate sections.
257         */
258        public void writetestCrudXXX_setDTOFieldsForTestReadAfterUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
259            indentPrintln("/*");
260            incrementIndent();
261            indentPrintln("A method to set the fields for a " + dtoObjectName  + " in the 'test read after update' section.");
262            indentPrintln("This dto is another (second) dto object being created for other tests.");
263            decrementIndent();
264            indentPrintln("*/");
265            indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestReadAfterUpdate(" + dtoObjectName + "Info expected) ");
266            openBrace();
267            for (MessageStructure ms: messageStructures) {
268                if (ms.getShortName().equals("id")) continue;
269                if (ms.getShortName().equals("typeKey")) continue;
270                if (ms.getShortName().equals("stateKey")) continue;
271                if (ms.getShortName().equals("meta")) continue;
272                if (ms.getShortName().equals("descr")) continue;
273                if (ms.getShortName().equals("attributes")) continue;
274                if (ms.getType().equals("String")) {
275                    indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
276                } else {
277                    indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
278                }
279            }
280            closeBrace();
281            indentPrintln("");
282        }
283    
284    }