From 67498a266d97f42e94726ecb14f5f5a465c79c21 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:31:51 -0500 Subject: [PATCH 01/75] removed readme for template, not necessary --- rest-readme.md | 110 ------------------------------------------------- 1 file changed, 110 deletions(-) delete mode 100644 rest-readme.md diff --git a/rest-readme.md b/rest-readme.md deleted file mode 100644 index 144327f..0000000 --- a/rest-readme.md +++ /dev/null @@ -1,110 +0,0 @@ -# REST HMVC Template - -This template gives you the base for building RESTFul web services with ColdBox in a modular fashion. This template will create an `api` module with a `v1` sub-module within it. It will leverage ColdBox 5 modular inherit entry points to mimic the URL resources to your modular design. - -In the `api/models` folder you will find our Universal REST Response object that can be leveraged as your base for building RESTFul services. - -``` -+ modules_app - + api - + models - + modules_app - + v1 -``` - -## Implicit Methods -The base handler implements an around handler approach to provide consistency and the following actions: - -- `onError` - Fires whenever there is a runtime exception in any action -- `onInvalidHTTPMethod` - Fires on invalid HTTP method access -- `onMissingAction` - Fires on invalid missing actions on handlers - -## Utility Functions -We also give you some utility functions for RESTFul building: - -- `routeNotFound` - Can be used to fire of route not founds via 404 -- `onExpectationFailed` - Can be called when an expectation of a request fails, like invalid parameters/headers etc. -- `onAuthorizationFailure` - Can be called to send a NOT Authorized status code and message. - -## HTTP Security -By default the base handlers leverages ColdBox method security via the `this.allowedMethods` structure: - -``` -this.allowedMethods = { - "index" : METHODS.GET, - "get" : METHODS.GET, - "list" : METHODS.GET, - "update" : METHODS.PUT & "," & METHODS.PATCH, - "delete" : METHODS.DELETE -}; -``` - -## HTTP Methods -The base handler contains a static construct called `METHODS` that implements basic HTTP Methods that you can use for messages and allowed methods. - -``` -METHODS = { - "HEAD" : "HEAD", - "GET" : "GET", - "POST" : "POST", - "PATCH" : "PATCH", - "PUT" : "PUT", - "DELETE" : "DELETE" -}; -``` - -## Status Codes -The base handler contains a static construct called `STATUS` that implements basic HTTP status codes you can use: - -``` -STATUS = { - "CREATED" : 201, - "ACCEPTED" : 202, - "SUCCESS" : 200, - "NO_CONTENT" : 204, - "RESET" : 205, - "PARTIAL_CONTENT" : 206, - "BAD_REQUEST" : 400, - "NOT_AUTHORIZED" : 401, - "NOT_FOUND" : 404, - "NOT_ALLOWED" : 405, - "NOT_ACCEPTABLE" : 406, - "TOO_MANY_REQUESTS" : 429, - "EXPECTATION_FAILED" : 417, - "INTERNAL_ERROR" : 500, - "NOT_IMPLEMENTED" : 501 -}; -``` - - -- - -## License -Apache License, Version 2.0. - -## Important Links - -Source Code -- https://github.com/coldbox-templates/rest-hmvc - -## Quick Installation - -Each application templates contains a `box.json` so it can leverage [CommandBox](http://www.ortussolutions.com/products/commandbox) for its dependencies. -Just go into each template directory and type: - -``` -box install -``` - -This will setup all the needed dependencies for each application template. You can then type: - -``` -box server start -``` - -And run the application. - ---- - -### THE DAILY BREAD - > "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12 \ No newline at end of file From ef6bcd9e8c6c8057cb4eaa377298f693bf12cc06 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:32:04 -0500 Subject: [PATCH 02/75] change char sets --- workbench/database/20200507_fluentapi.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workbench/database/20200507_fluentapi.sql b/workbench/database/20200507_fluentapi.sql index b5dde79..1d637e9 100644 --- a/workbench/database/20200507_fluentapi.sql +++ b/workbench/database/20200507_fluentapi.sql @@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `rants` ( PRIMARY KEY (`id`), KEY `fk_rants_userId` (`userId`), CONSTRAINT `fk_rants_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4; -- Dumping data for table fluentapi.rants: ~23 rows (approximately) /*!40000 ALTER TABLE `rants` DISABLE KEYS */; @@ -61,7 +61,7 @@ CREATE TABLE IF NOT EXISTS `users` ( PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`) -) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4; -- Dumping data for table fluentapi.users: ~6 rows (approximately) /*!40000 ALTER TABLE `users` DISABLE KEYS */; From 09783cc623c1d6952a86eb3b4e70b622ffcb4dd2 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:32:14 -0500 Subject: [PATCH 03/75] updating formatting rules to latest --- .cfformat.json | 117 +++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/.cfformat.json b/.cfformat.json index c97a347..ff8178c 100644 --- a/.cfformat.json +++ b/.cfformat.json @@ -1,58 +1,61 @@ { - "alignment.consecutive.assignments":false, - "alignment.consecutive.params":false, - "alignment.consecutive.properties":false, - "array.empty_padding":false, - "array.multiline.element_count":4, - "array.multiline.leading_comma":false, - "array.multiline.leading_comma.padding":true, - "array.multiline.min_length":40, - "array.padding":true, - "binary_operators.padding":true, - "brackets.padding":true, - "comment.asterisks":"align", - "for_loop_semicolons.padding":true, - "function_anonymous.empty_padding":false, - "function_anonymous.group_to_block_spacing":"spaced", - "function_anonymous.multiline.element_count":4, - "function_anonymous.multiline.leading_comma":false, - "function_anonymous.multiline.leading_comma.padding":true, - "function_anonymous.multiline.min_length":40, - "function_anonymous.padding":true, - "function_call.casing.builtin":"cfdocs", - "function_call.casing.userdefined":"camel", - "function_call.empty_padding":false, - "function_call.multiline.element_count":4, - "function_call.multiline.leading_comma":false, - "function_call.multiline.leading_comma.padding":true, - "function_call.multiline.min_length":40, - "function_call.padding":true, - "function_declaration.empty_padding":false, - "function_declaration.group_to_block_spacing":"spaced", - "function_declaration.multiline.element_count":4, - "function_declaration.multiline.leading_comma":false, - "function_declaration.multiline.leading_comma.padding":true, - "function_declaration.multiline.min_length":40, - "function_declaration.padding":true, - "indent_size":4, - "keywords.block_to_keyword_spacing":"spaced", - "keywords.empty_group_spacing":false, - "keywords.group_to_block_spacing":"spaced", - "keywords.padding_inside_group":true, - "keywords.spacing_to_block":"spaced", - "keywords.spacing_to_group":true, - "max_columns":120, - "method_call.chain.multiline":3, - "newline":"\n", - "parentheses.padding":true, - "strings.attributes.quote":"double", - "strings.quote":"double", - "struct.empty_padding":false, - "struct.multiline.element_count":4, - "struct.multiline.leading_comma":false, - "struct.multiline.leading_comma.padding":true, - "struct.multiline.min_length":40, - "struct.padding":true, - "struct.separator":": ", - "tab_indent":true -} + "array.empty_padding": false, + "array.padding": true, + "array.multiline.min_length": 40, + "array.multiline.element_count": 2, + "array.multiline.leading_comma.padding": true, + "array.multiline.leading_comma": false, + "alignment.consecutive.assignments": true, + "alignment.consecutive.properties": true, + "alignment.consecutive.params": true, + "brackets.padding": true, + "comment.asterisks": "align", + "binary_operators.padding": true, + "for_loop_semicolons.padding": true, + "function_call.empty_padding": false, + "function_call.padding": true, + "function_call.multiline.leading_comma.padding": true, + "function_call.casing.builtin": "cfdocs", + "function_call.casing.userdefined": "camel", + "function_call.multiline.element_count": 3, + "function_call.multiline.leading_comma": false, + "function_call.multiline.min_length": 40, + "function_declaration.padding": true, + "function_declaration.empty_padding": false, + "function_declaration.multiline.leading_comma": false, + "function_declaration.multiline.leading_comma.padding": true, + "function_declaration.multiline.element_count": 3, + "function_declaration.multiline.min_length": 40, + "function_declaration.group_to_block_spacing": "compact", + "function_anonymous.empty_padding": false, + "function_anonymous.group_to_block_spacing": "compact", + "function_anonymous.multiline.element_count": 3, + "function_anonymous.multiline.leading_comma": false, + "function_anonymous.multiline.leading_comma.padding": true, + "function_anonymous.multiline.min_length": 40, + "function_anonymous.padding": true, + "indent_size": 4, + "keywords.block_to_keyword_spacing": "spaced", + "keywords.group_to_block_spacing": "spaced", + "keywords.padding_inside_group": true, + "keywords.spacing_to_block": "spaced", + "keywords.spacing_to_group": true, + "keywords.empty_group_spacing": false, + "max_columns": 120, + "metadata.multiline.element_count": 3, + "metadata.multiline.min_length": 40, + "newline":"\n", + "property.multiline.element_count": 3, + "property.multiline.min_length": 40, + "parentheses.padding": true, + "strings.quote": "double", + "strings.attributes.quote": "double", + "struct.separator": " : ", + "struct.padding": true, + "struct.empty_padding": false, + "struct.multiline.leading_comma": false, + "struct.multiline.leading_comma.padding": true, + "struct.multiline.element_count": 2, + "struct.multiline.min_length": 40, + "tab_indent": true +} \ No newline at end of file From 15445a00d4cc464a7adf5dcf20b0bd58f1ad26d8 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:32:29 -0500 Subject: [PATCH 04/75] renamed for generic presso --- readme.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index b422efe..4022f16 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,6 @@ -# 2020-ITB - Modern Functional & Fluent CFML REST APIs +# Modern Functional & Fluent CFML REST APIs -This repo is the demo repo for the presentation given at Into the Box 2020. - -## Slides: - -The slides can be found at: https://drive.google.com/file/d/1C-__UfDdvvjpIGKtx4B_J14Z2frnJUKL/view?usp=sharing +This repo is a demo for our presentation on building modern functional & fluent CFML REST APIs. ## App Setup From 23b53905a9be67a2e1cd1e70095d72c0b78211a7 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:33:32 -0500 Subject: [PATCH 05/75] added lucee + adobe support --- box.json | 55 +++++++++++++++++++++++++++++++---------------- server-lucee.json | 12 +++++++++++ server.json | 5 +++++ 3 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 server-lucee.json diff --git a/box.json b/box.json index 3aa8d7d..2a096a1 100644 --- a/box.json +++ b/box.json @@ -1,27 +1,37 @@ { "name":"FluentAPI", "version":"1.0.0", - "location":"", - "author":"You", + "author":"Ortus Solutions", "slug":"fluentapi", - "createPackageDirectory":false, "type":"mvc", - "homepage":"https://github.com/coldbox-templates/rest-hmvc", - "documentation":"https://github.com/coldbox-templates/rest-hmvc", + "homepage":"https://github.com/lmajano/modern-functional-fluent-cfml-rest", + "documentation":"https://github.com/lmajano/modern-functional-fluent-cfml-rest", "repository":{ "type":"git", - "url":"https://github.com/coldbox-templates/rest-hmvc" + "url":"https://github.com/lmajano/modern-functional-fluent-cfml-rest" }, - "bugs":"https://github.com/coldbox-templates/rest-hmvc/issues", - "shortDescription":"A modular API RESTFul template", - "contributors":[], + "bugs":"https://github.com/lmajano/modern-functional-fluent-cfml-rest/issues", + "shortDescription":"Demo repo for functional APIs", + "contributors":[ + "Luis Majano ", + "Gavin Pickin " + ], "ignore":[], "devDependencies":{ "relax":"^4.1.0+174", - "testbox":"^3.0.0", + "route-visualizer":"^1.4.0+24", + "testbox":"^4.0.0", "commandbox-dotenv":"*", "commandbox-cfconfig":"*", - "commandbox-cfformat":"*" + "commandbox-cfformat":"*", + "commandbox-migrations":"*" + }, + "dependencies":{ + "coldbox":"6.0.0-RC", + "cbswagger":"^2.1.1+118", + "cbvalidation":"^2.1.0+126", + "cors":"3.0.2", + "mementifier":"^2.1.0+100" }, "installPaths":{ "coldbox":"coldbox/", @@ -33,17 +43,24 @@ "cors":"modules/cors/", "mementifier":"modules/mementifier/" }, - "dependencies":{ - "coldbox":"5.6.2", - "cbswagger":"^2.1.1+118", - "cbvalidation":"^2.1.0+126", - "route-visualizer":"^1.4.0+24", - "cors":"^3.0.3", - "mementifier":"^2.1.0+100" - }, "scripts":{ + "start:lucee" : "server start serverConfigFile=server-lucee.json --force", + "start:adobe" : "server start serverConfigFile=server.json --force", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:check":"cfformat check modules_app/**/*.cfc,tests/specs/**/*.cfc --verbose" + }, + "cfmigrations":{ + "migrationsDirectory":"resources/database/migrations", + "schema":"${DB_SCHEMA}", + "connectionInfo":{ + "bundleName":"${DB_BUNDLENAME}", + "bundleVersion":"${DB_BUNDLEVERSION}", + "password":"${DB_PASSWORD}", + "connectionString":"${DB_CONNECTIONSTRING}", + "class":"${DB_CLASS}", + "username":"${DB_USER}" + }, + "defaultGrammar":"AutoDiscover@qb" } } diff --git a/server-lucee.json b/server-lucee.json new file mode 100644 index 0000000..2dc28f2 --- /dev/null +++ b/server-lucee.json @@ -0,0 +1,12 @@ +{ + "app":{ + "serverHomeDirectory":".engine/lucee5", + "cfengine":"lucee@5" + }, + "web":{ + "directoryBrowsing":true, + "rewrites":{ + "enable":true + } + } +} \ No newline at end of file diff --git a/server.json b/server.json index a27b424..77de72e 100644 --- a/server.json +++ b/server.json @@ -1,5 +1,10 @@ { + "app":{ + "serverHomeDirectory":".engine/adobe2018", + "cfengine":"adobe@2018" + }, "web":{ + "directoryBrowsing":true, "rewrites":{ "enable":true } From 36546aa7aa355157cf1465e3e9cc5f03ac574c4b Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:43:08 -0500 Subject: [PATCH 06/75] added migrations --- box.json | 2 +- .../2020_05_15_183916_buildrants.cfc | 37 +++++++++++++++ .../2020_05_15_184033_seedrants.cfc | 46 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100755 resources/database/migrations/2020_05_15_183916_buildrants.cfc create mode 100755 resources/database/migrations/2020_05_15_184033_seedrants.cfc diff --git a/box.json b/box.json index 2a096a1..20a7e8d 100644 --- a/box.json +++ b/box.json @@ -52,7 +52,7 @@ }, "cfmigrations":{ "migrationsDirectory":"resources/database/migrations", - "schema":"${DB_SCHEMA}", + "schema":"${DB_DATABASE}", "connectionInfo":{ "bundleName":"${DB_BUNDLENAME}", "bundleVersion":"${DB_BUNDLEVERSION}", diff --git a/resources/database/migrations/2020_05_15_183916_buildrants.cfc b/resources/database/migrations/2020_05_15_183916_buildrants.cfc new file mode 100755 index 0000000..d8aa8f7 --- /dev/null +++ b/resources/database/migrations/2020_05_15_183916_buildrants.cfc @@ -0,0 +1,37 @@ +component { + + function up( schema, query ) { + queryExecute( " + CREATE TABLE IF NOT EXISTS `users` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `username` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `username` (`username`), + UNIQUE KEY `email` (`email`) + ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4; + " ); + + queryExecute( " + CREATE TABLE IF NOT EXISTS `rants` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `body` text NOT NULL, + `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `userId` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_rants_userId` (`userId`), + CONSTRAINT `fk_rants_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE + ) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4; + " ); + } + + function down( schema, query ) { + schema.drop( "rants" ); + schema.drop( "users" ); + } + +} diff --git a/resources/database/migrations/2020_05_15_184033_seedrants.cfc b/resources/database/migrations/2020_05_15_184033_seedrants.cfc new file mode 100755 index 0000000..81a5681 --- /dev/null +++ b/resources/database/migrations/2020_05_15_184033_seedrants.cfc @@ -0,0 +1,46 @@ +component { + + function up( schema, query ) { + queryExecute( " + INSERT INTO `users` (`id`, `username`, `email`, `password`, `createdDate`, `modifiedDate`) VALUES + (2, 'gpickin', 'gavin@ortussolutions.com', '$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.', '2018-10-04 17:55:19', '2018-10-04 17:55:19'), + (3, 'luis', 'lmajano@ortussolutions.com', '$2a$12$kSM/7Q5WgJ/xaKfLYwbPj.4QVJZo7tonT/h/PFDoUwfW3GDV/AttC', '2018-10-05 09:07:14', '2018-10-05 09:07:14'), + (4, 'brad', 'brad@ortussolutions.com', '$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6', '2018-10-05 09:29:37', '2018-10-05 09:29:37'), + (5, 'javier', 'jquintero@ortussolutions.com', '$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W', '2018-10-05 09:30:32', '2018-10-05 09:30:32'), + (6, 'scott', 'scott@scott.com', '$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.', '2018-10-05 09:32:07', '2018-10-05 09:32:07'), + (7, 'mike', 'mikep@netxn.com', '$2a$12$WWUwFEAoDGx.vB0jE54xser1myMUSwUMYo/aNn0cSGa8l6DQe67Q2', '2018-10-05 09:33:00', '2018-10-05 09:33:00'); + " ); + + queryExecute( " + INSERT INTO `rants` (`id`, `body`, `createdDate`, `modifiedDate`, `userId`) VALUES + (4, 'Another rant', '2020-05-03 23:00:07', '2020-05-03 23:00:07', 2), + (6, 'Another rant, where\'s my soapbox2', '2020-05-03 23:07:39', '2020-05-04 11:22:48', 3), + (7, 'Another rant, where\'s my soapbox23', '2020-05-03 23:20:22', '2020-05-07 11:43:07', 2), + (8, 'Another rant, where\'s my soapbox2', '2020-05-04 11:21:31', '2020-05-04 11:21:31', 2), + (9, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:18', '2020-05-04 12:05:18', 2), + (10, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:44', '2020-05-04 12:05:44', 2), + (11, 'Another rant, where\'s my soapbox2', '2020-05-04 20:58:28', '2020-05-04 20:58:28', 2), + (12, 'Another rant, where\'s my soapbox2', '2020-05-04 20:59:44', '2020-05-04 20:59:44', 2), + (13, 'Another rant, where\'s my soapbox2', '2020-05-04 21:06:16', '2020-05-04 21:06:16', 2), + (14, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:03', '2020-05-04 21:09:03', 2), + (15, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:13', '2020-05-04 21:09:13', 2), + (16, 'Another rant, where\'s my soapbox2', '2020-05-04 21:15:10', '2020-05-04 21:15:10', 2), + (18, 'Another rant, where\'s my soapbox2', '2020-05-07 09:29:06', '2020-05-07 09:29:06', 2), + (19, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:38', '2020-05-07 09:30:38', 2), + (20, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:46', '2020-05-07 09:30:46', 2), + (23, 'Another rant, where\'s my soapbox2', '2020-05-07 09:36:04', '2020-05-07 09:36:04', 2), + (24, 'Another rant, where\'s my soapbox2', '2020-05-07 09:37:03', '2020-05-07 09:37:03', 2), + (25, 'Another rant, where\'s my soapbox2', '2020-05-07 09:46:15', '2020-05-07 09:46:15', 2), + (110, 'Testing test test', '2020-05-07 22:18:43', '2020-05-07 22:18:43', 2), + (111, 'Testing test test', '2020-05-07 22:19:31', '2020-05-07 22:19:31', 2), + (112, 'Scott likes me preso', '2020-05-07 22:19:37', '2020-05-07 22:19:37', 5), + (113, 'Scott seems to like my preso', '2020-05-07 22:20:32', '2020-05-07 22:20:32', 2); + " ); + } + + function down( schema, query ) { + queryExecute( "truncate rants" ); + queryExecute( "truncate users" ); + } + +} From 826e7b8df61fbd67210e4067bb7a4175a698f52f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 May 2020 18:53:06 -0500 Subject: [PATCH 07/75] coldbox 6 updates --- config/Application.cfc | 14 +- config/CacheBox.cfc | 68 +++--- config/Coldbox.cfc | 286 ++++++++++++----------- config/Router.cfc | 8 +- config/WireBox.cfc | 47 ++-- modules_app/api/handlers/BaseHandler.cfc | 16 +- server.json | 4 +- 7 files changed, 214 insertions(+), 229 deletions(-) diff --git a/config/Application.cfc b/config/Application.cfc index 23c5ad0..66424cb 100644 --- a/config/Application.cfc +++ b/config/Application.cfc @@ -1,7 +1,9 @@ -/** -* This is a protection Application cfm for the config file. You do not -* need to modify this file -*/ -component{ +/** + * This is a protection Application cfm for the config file. You do not + * need to modify this file + */ +component { + abort; -} \ No newline at end of file + +} diff --git a/config/CacheBox.cfc b/config/CacheBox.cfc index 8f27b49..a994fb1 100644 --- a/config/CacheBox.cfc +++ b/config/CacheBox.cfc @@ -1,50 +1,46 @@ component{ - /** - * Configure CacheBox for ColdBox Application Operation - */ + * Configure CacheBox for ColdBox Application Operation + */ function configure(){ - // The CacheBox configuration structure DSL cacheBox = { // LogBox config already in coldbox app, not needed - // logBoxConfig = "coldbox.system.web.config.LogBox", - + // logBoxConfig = "coldbox.system.web.config.LogBox", + // The defaultCache has an implicit name "default" which is a reserved cache name // It also has a default provider of cachebox which cannot be changed. // All timeouts are in minutes - defaultCache = { - objectDefaultTimeout = 120, //two hours default - objectDefaultLastAccessTimeout = 30, //30 minutes idle time - useLastAccessTimeouts = true, - reapFrequency = 5, - freeMemoryPercentageThreshold = 0, - evictionPolicy = "LRU", - evictCount = 1, - maxObjects = 300, - objectStore = "ConcurrentStore", //guaranteed objects - coldboxEnabled = true + defaultCache : { + objectDefaultTimeout : 120, // two hours default + objectDefaultLastAccessTimeout : 30, // 30 minutes idle time + useLastAccessTimeouts : true, + reapFrequency : 5, + freeMemoryPercentageThreshold : 0, + evictionPolicy : "LRU", + evictCount : 1, + maxObjects : 300, + objectStore : "ConcurrentStore", // guaranteed objects + coldboxEnabled : true }, - // Register all the custom named caches you like here - caches = { + caches : { // Named cache for all coldbox event and view template caching - template = { - provider = "coldbox.system.cache.providers.CacheBoxColdBoxProvider", - properties = { - objectDefaultTimeout = 120, - objectDefaultLastAccessTimeout = 30, - useLastAccessTimeouts = true, - freeMemoryPercentageThreshold = 0, - reapFrequency = 5, - evictionPolicy = "LRU", - evictCount = 2, - maxObjects = 300, - objectStore = "ConcurrentSoftReferenceStore" //memory sensitive + template : { + provider : "coldbox.system.cache.providers.CacheBoxColdBoxProvider", + properties : { + objectDefaultTimeout : 120, + objectDefaultLastAccessTimeout : 30, + useLastAccessTimeouts : true, + freeMemoryPercentageThreshold : 0, + reapFrequency : 5, + evictionPolicy : "LRU", + evictCount : 2, + maxObjects : 300, + objectStore : "ConcurrentSoftReferenceStore" // memory sensitive } - } - } + } + } }; - } - -} \ No newline at end of file + } +} diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index f6690df..60a7fa3 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -1,192 +1,194 @@ component{ - // Configure ColdBox Application function configure(){ - - // coldbox directives + /** + * -------------------------------------------------------------------------- + * ColdBox Directives + * -------------------------------------------------------------------------- + * Here you can configure ColdBox for operation. Remember tha these directives below + * are for PRODUCTION. If you want different settings for other environments make sure + * you create the appropriate functions and define the environment in your .env or + * in the `environments` struct. + */ coldbox = { - //Application Setup - appName = getSystemSetting( "APPNAME", "Your app name here" ), - eventName = "event", - - //Development Settings - reinitPassword = "", - handlersIndexAutoReload = true, - - //Implicit Events - defaultEvent = "v1:echo.index", - requestStartHandler = "", - requestEndHandler = "", - applicationStartHandler = "", - applicationEndHandler = "", - sessionStartHandler = "", - sessionEndHandler = "", - missingTemplateHandler = "", - - //Extension Points - applicationHelper = "", - viewsHelper = "", - modulesExternalLocation = [], - viewsExternalLocation = "", - layoutsExternalLocation = "", - handlersExternalLocation = "", - requestContextDecorator = "", - controllerDecorator = "", - - //Error/Exception Handling - invalidHTTPMethodHandler = "", - exceptionHandler = "", - invalidEventHandler = "", - customErrorTemplate = "", - - //Application Aspects - handlerCaching = false, - eventCaching = false, - viewCaching = false, + // Application Setup + appName : getSystemSetting( "APPNAME", "Your app name here" ), + eventName : "event", + // Development Settings + reinitPassword : "", + reinitKey : "fwreinit", + handlersIndexAutoReload : true, + // Implicit Events + defaultEvent : "v1:Echo.index", + requestStartHandler : "", + requestEndHandler : "", + applicationStartHandler : "", + applicationEndHandler : "", + sessionStartHandler : "", + sessionEndHandler : "", + missingTemplateHandler : "", + // Extension Points + applicationHelper : "", + viewsHelper : "", + modulesExternalLocation : [], + viewsExternalLocation : "", + layoutsExternalLocation : "", + handlersExternalLocation : "", + requestContextDecorator : "", + controllerDecorator : "", + // Error/Exception Handling + invalidHTTPMethodHandler : "", + exceptionHandler : "v1:Echo.onError", + invalidEventHandler : "", + customErrorTemplate : "", + // Application Aspects + handlerCaching : false, + eventCaching : false, + viewCaching : false, // Will automatically do a mapDirectory() on your `models` for you. - autoMapModels = true, - jsonPayloadToRC = true + autoMapModels : true, + // Auto converts a json body payload into the RC + jsonPayloadToRC : true }; - // custom settings - settings = { - - }; - - // environment settings, create a detectEnvironment() method to detect it yourself. - // create a function with the name of the environment so it can be executed if that environment is detected - // the value of the environment is a list of regex patterns to match the cgi.http_host. - environments = { - development = "localhost,127\.0\.0\.1" - }; - - // Module Directives + /** + * -------------------------------------------------------------------------- + * Custom Settings + * -------------------------------------------------------------------------- + */ + settings = {}; + + /** + * -------------------------------------------------------------------------- + * Environment Detection + * -------------------------------------------------------------------------- + * By default we look in your `.env` file for an `environment` key, if not, + * then we look into this structure or if you have a function called `detectEnvironment()` + * If you use this setting, then each key is the name of the environment and the value is + * the regex patterns to match against cgi.http_host. + * + * Uncomment to use, but make sure your .env ENVIRONMENT key is also removed. + */ + // environments = { development : "localhost,^127\.0\.0\.1" }; + + /** + * -------------------------------------------------------------------------- + * Module Loading Directives + * -------------------------------------------------------------------------- + */ modules = { // An array of modules names to load, empty means all of them - include = [], + include : [], // An array of modules names to NOT load, empty means none - exclude = [] + exclude : [] }; - //LogBox DSL + /** + * -------------------------------------------------------------------------- + * Application Logging (https://logbox.ortusbooks.com) + * -------------------------------------------------------------------------- + * By Default we log to the console, but you can add many appenders or destinations to log to. + * You can also choose the logging level of the root logger, or even the actual appender. + */ logBox = { // Define Appenders - appenders = { - coldboxTracer = { class="coldbox.system.logging.appenders.ConsoleAppender" } - }, + appenders : { coldboxTracer : { class : "coldbox.system.logging.appenders.ConsoleAppender" } }, // Root Logger - root = { levelmax="INFO", appenders="*" }, + root : { levelmax : "INFO", appenders : "*" }, // Implicit Level Categories - info = [ "coldbox.system" ] - }; - - //Layout Settings - layoutSettings = { - defaultLayout = "", - defaultView = "" - }; - - //Interceptor Settings - interceptorSettings = { - customInterceptionPoints = "" + info : [ "coldbox.system" ] }; - //Register interceptors as an array, we need order - interceptors = [ - ]; - - // module setting overrides + /** + * -------------------------------------------------------------------------- + * Layout Settings + * -------------------------------------------------------------------------- + */ + layoutSettings = { defaultLayout : "", defaultView : "" }; + + /** + * -------------------------------------------------------------------------- + * Custom Interception Points + * -------------------------------------------------------------------------- + */ + interceptorSettings = { customInterceptionPoints : [] }; + + /** + * -------------------------------------------------------------------------- + * Application Interceptors + * -------------------------------------------------------------------------- + * Remember that the order of declaration is the order they will be registered and fired + */ + interceptors = []; + + /** + * -------------------------------------------------------------------------- + * Module Settings + * -------------------------------------------------------------------------- + * Each module has it's own configuration structures, so make sure you follow + * the module's instructions on settings. + * + * Each key is the name of the module: + * + * myModule = { + * + * } + */ moduleSettings = { - cbswagger = { + cbswagger : { // The route prefix to search. Routes beginning with this prefix will be determined to be api routes - "routes" : [ "api" ], + "routes" : [ "api" ], // The default output format: json or yml // Any routes to exclude - "excludeRoutes" : [], + "excludeRoutes" : [], "defaultFormat" : "json", // A convention route, relative to your app root, where request/response samples are stored ( e.g. resources/apidocs/responses/[module].[handler].[action].[HTTP Status Code].json ) - "samplesPath" : "resources/apidocs", + "samplesPath" : "resources/apidocs", // Information about your API - "info" :{ + "info" : { // A title for your API - "title" : "Fluent API for SoapBox Twitter clone", + "title" : "Fluent API for SoapBox Twitter clone", // A description of your API - "description" : "This Fluent API provides data the for SoapBox Twitter clone", + "description" : "This Fluent API provides data the for SoapBox Twitter clone", // A terms of service URL for your API - "termsOfService" : "", - //The contact email address - "contact" :{ - "name": "Gavin Pickin", - "url": "https://www.ortussolutions.com", - "email": "gavin@ortussolutions.com" + "termsOfService" : "", + // The contact email address + "contact" : { + "name" : "Gavin Pickin", + "url" : "https://www.ortussolutions.com", + "email" : "gavin@ortussolutions.com" }, - //A url to the License of your API - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + // A url to the License of your API + "license" : { + "name" : "Apache 2.0", + "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" }, - //The version of your API - "version":"1.0.0" + // The version of your API + "version" : "1.0.0" }, - // https://swagger.io/specification/#serverObject "servers" : [ { - "url" : "http://127.0.0.1:60146/", - "description" : "Local Development" + "url" : "http://127.0.0.1:60146/", + "description" : "Local Development" } ], - // An element to hold various schemas for the specification. // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject "components" : { - // Define your security schemes here // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject "securitySchemes" : {} } } }; - - /* - - // flash scope configuration - flash = { - scope = "session,client,cluster,ColdboxCache,or full path", - properties = {}, // constructor properties for the flash scope implementation - inflateToRC = true, // automatically inflate flash data into the RC scope - inflateToPRC = false, // automatically inflate flash data into the PRC scope - autoPurge = true, // automatically purge flash data for you - autoSave = true // automatically save flash scopes at end of a request and on relocations. - }; - - //Register Layouts - layouts = [ - { name = "login", - file = "Layout.tester.cfm", - views = "vwLogin,test", - folders = "tags,pdf/single" - } - ]; - - //Conventions - conventions = { - handlersLocation = "handlers", - viewsLocation = "views", - layoutsLocation = "layouts", - modelsLocation = "models", - eventAction = "index" - }; - - */ - } /** - * Development environment - */ + * Development environment + */ function development(){ - coldbox.customErrorTemplate = "/coldbox/system/includes/BugReport.cfm"; + // coldbox.customErrorTemplate = "/coldbox/system/exceptions/BugReport.cfm"; + coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; } - -} \ No newline at end of file +} diff --git a/config/Router.cfc b/config/Router.cfc index 48a9fc5..bfa57f8 100644 --- a/config/Router.cfc +++ b/config/Router.cfc @@ -1,4 +1,4 @@ -component{ +component { function configure(){ // Set Full Rewrites @@ -15,12 +15,12 @@ component{ */ // A nice healthcheck route example - route("/healthcheck",function(event,rc,prc){ + route( "/healthcheck", function( event, rc, prc ){ return "Ok!"; - }); + } ); // Conventions based routing route( ":handler/:action?" ).end(); } -} \ No newline at end of file +} diff --git a/config/WireBox.cfc b/config/WireBox.cfc index 3aafc01..12963f8 100644 --- a/config/WireBox.cfc +++ b/config/WireBox.cfc @@ -1,46 +1,31 @@ -component extends="coldbox.system.ioc.config.Binder"{ - +component extends = "coldbox.system.ioc.config.Binder"{ /** - * Configure WireBox, that's it! - */ + * Configure WireBox, that's it! + */ function configure(){ - // The WireBox configuration structure DSL wireBox = { // Scope registration, automatically register a wirebox injector instance on any CF scope // By default it registeres itself on application scope - scopeRegistration = { - enabled = true, - scope = "application", // server, cluster, session, application - key = "wireBox" + scopeRegistration : { + enabled : true, + scope : "application", // server, cluster, session, application + key : "wireBox" }, - // DSL Namespace registrations - customDSL = { - // namespace = "mapping name" - }, - + customDSL : {}, // Custom Storage Scopes - customScopes = { - // annotationName = "mapping name" - }, - + customScopes : {}, // Package scan locations - scanLocations = [], - + scanLocations : [], // Stop Recursions - stopRecursions = [], - + stopRecursions : [], // Parent Injector to assign to the configured injector, this must be an object reference - parentInjector = "", - + parentInjector : "", // Register all event listeners here, they are created in the specified order - listeners = [ - // { class="", name="", properties={} } - ] + listeners : [] }; - - // Map Bindings below - } -} \ No newline at end of file + // Map Bindings below + } +} diff --git a/modules_app/api/handlers/BaseHandler.cfc b/modules_app/api/handlers/BaseHandler.cfc index 68268d0..6be62e0 100644 --- a/modules_app/api/handlers/BaseHandler.cfc +++ b/modules_app/api/handlers/BaseHandler.cfc @@ -75,7 +75,7 @@ component extends="coldbox.system.EventHandler" { // start a resource timer var stime = getTickCount(); // prepare our response object - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); // prepare argument execution var args = { event: arguments.event, rc: arguments.rc, prc: arguments.prc }; structAppend( args, arguments.eventArguments ); @@ -207,7 +207,7 @@ component extends="coldbox.system.EventHandler" { // Verify response exists, else create one if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); } // Setup General Error Response @@ -298,7 +298,7 @@ component extends="coldbox.system.EventHandler" { ); // Setup Response - prc.response = getModel( "Response@api" ) + prc.response = getInstance( "Response@api" ) .setError( true ) .addMessage( "InvalidHTTPMethod Execution of (#arguments.faultAction#): #event.getHTTPMethod()#" ) .setStatusCode( STATUS.NOT_ALLOWED ) @@ -327,7 +327,7 @@ component extends="coldbox.system.EventHandler" { eventArguments ) { // Setup Response - prc.response = getModel( "Response@api" ) + prc.response = getInstance( "Response@api" ) .setError( true ) .addMessage( "Action '#arguments.missingAction#' could not be found" ) .setStatusCode( STATUS.NOT_ALLOWED ) @@ -355,7 +355,7 @@ component extends="coldbox.system.EventHandler" { abort = false ) { if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); } // case when the a jwt token was valid, but expired @@ -388,7 +388,7 @@ component extends="coldbox.system.EventHandler" { abort = false ) { if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); } prc.response @@ -422,7 +422,7 @@ component extends="coldbox.system.EventHandler" { */ function onInvalidRoute( event, rc, prc ) { if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); } prc.response @@ -443,7 +443,7 @@ component extends="coldbox.system.EventHandler" { prc = getRequestCollection( private = true ) ) { if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getModel( "Response@api" ); + prc.response = getInstance( "Response@api" ); } prc.response diff --git a/server.json b/server.json index 77de72e..ac432e4 100644 --- a/server.json +++ b/server.json @@ -1,10 +1,10 @@ { "app":{ - "serverHomeDirectory":".engine/adobe2018", + "serverHomeDirectory":".engine/adobe2018", "cfengine":"adobe@2018" }, "web":{ - "directoryBrowsing":true, + "directoryBrowsing":true, "rewrites":{ "enable":true } From 7ac0a8be157870233bb20d050cc0051cee6c99a1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 09:50:50 -0500 Subject: [PATCH 08/75] env updates and ignores --- .env.example | 5 ++++- .gitignore | 2 ++ box.json | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index f814c93..716798e 100644 --- a/.env.example +++ b/.env.example @@ -3,11 +3,14 @@ APPNAME=fluentAPI ENVIRONMENT=development # Database Information +DB_CONNECTIONSTRING=jdbc:mysql://127.0.0.1:3306/fluentapi?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true DB_CLASS=com.mysql.jdbc.Driver +DB_BUNDLENAME=com.mysql.jdbc +DB_BUNDLEVERSION=5.1.38 DB_DRIVER=MySQL DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=coldbox +DB_DATABASE=fluentapi DB_USER=root DB_PASSWORD= diff --git a/.gitignore b/.gitignore index fe4120b..4ffba39 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ settings.xml WEB-INF .env +.engine/** +.vscode/** # logs + tests logs/** diff --git a/box.json b/box.json index 20a7e8d..62c05b5 100644 --- a/box.json +++ b/box.json @@ -44,8 +44,8 @@ "mementifier":"modules/mementifier/" }, "scripts":{ - "start:lucee" : "server start serverConfigFile=server-lucee.json --force", - "start:adobe" : "server start serverConfigFile=server.json --force", + "start:lucee":"server start serverConfigFile=server-lucee.json --force", + "start:adobe":"server start serverConfigFile=server.json --force", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:check":"cfformat check modules_app/**/*.cfc,tests/specs/**/*.cfc --verbose" From cf86b0505919132a3543227c486fc9b338a0a91f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 09:57:10 -0500 Subject: [PATCH 09/75] added admin passwords --- .env.example | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.example b/.env.example index 716798e..00d4b3b 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ # ColdBox Environment APPNAME=fluentAPI +ADMIN_PASSWORD=fluentapi ENVIRONMENT=development # Database Information From 1782433253f85b0c412a63075ae1b7b8faf59de4 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 10:13:23 -0500 Subject: [PATCH 10/75] cleanup --- modules_app/api/ModuleConfig.cfc | 70 +--- modules_app/api/handlers/BaseHandler.cfc | 456 ----------------------- modules_app/api/models/Response.cfc | 217 ----------- 3 files changed, 6 insertions(+), 737 deletions(-) delete mode 100644 modules_app/api/handlers/BaseHandler.cfc delete mode 100644 modules_app/api/models/Response.cfc diff --git a/modules_app/api/ModuleConfig.cfc b/modules_app/api/ModuleConfig.cfc index eaeb651..5547df2 100644 --- a/modules_app/api/ModuleConfig.cfc +++ b/modules_app/api/ModuleConfig.cfc @@ -1,57 +1,12 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * Module Config + */ component { // Module Properties this.title = "api"; - this.author = ""; - this.webURL = ""; - this.description = ""; + this.description = "Base API Module"; this.version = "1.0.0"; - // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; - // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa - this.layoutParentLookup = true; // Module Entry Point this.entryPoint = "api"; // Inheritable entry point. @@ -60,26 +15,13 @@ component { this.modelNamespace = "api"; // CF Mapping this.cfmapping = "api"; - // Auto-map models - this.autoMapModels = true; // Module Dependencies this.dependencies = []; + /** + * Configure the module + */ function configure() { - // parent settings - parentSettings = {}; - - // module settings - stored in modules.name.settings - settings = {}; - - // Layout Settings - layoutSettings = { defaultLayout: "" }; - - // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; - - // Custom Declared Interceptors - interceptors = []; } /** diff --git a/modules_app/api/handlers/BaseHandler.cfc b/modules_app/api/handlers/BaseHandler.cfc deleted file mode 100644 index 6be62e0..0000000 --- a/modules_app/api/handlers/BaseHandler.cfc +++ /dev/null @@ -1,456 +0,0 @@ -/** - * ******************************************************************************** - * Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp - * www.ortussolutions.com - * ******************************************************************************** - * Base RESTFul handler spice up as needed. - * This handler will create a Response model and prepare it for your actions to use - * to produce RESTFul responses. - */ -component extends="coldbox.system.EventHandler" { - - // Pseudo "constants" used in API Response/Method parsing - property name="METHODS"; - property name="STATUS"; - - // Verb aliases - in case we are dealing with legacy browsers or servers ( e.g. IIS7 default ) - METHODS = { - "HEAD": "HEAD", - "GET": "GET", - "POST": "POST", - "PATCH": "PATCH", - "PUT": "PUT", - "DELETE": "DELETE" - }; - - // HTTP STATUS CODES - STATUS = { - "CREATED": 201, - "ACCEPTED": 202, - "SUCCESS": 200, - "NO_CONTENT": 204, - "RESET": 205, - "PARTIAL_CONTENT": 206, - "BAD_REQUEST": 400, - "NOT_AUTHORIZED": 403, - "NOT_AUTHENTICATED": 401, - "NOT_FOUND": 404, - "NOT_ALLOWED": 405, - "NOT_ACCEPTABLE": 406, - "TOO_MANY_REQUESTS": 429, - "EXPECTATION_FAILED": 417, - "INTERNAL_ERROR": 500, - "NOT_IMPLEMENTED": 501 - }; - - // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; - this.aroundHandler_except = ""; - - // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='#METHODS.POST#,#METHODS.DELETE#',index='#METTHOD.GET#'} - this.allowedMethods = { - "index": METHODS.GET, - "get": METHODS.GET, - "create": METHODS.POST, - "list": METHODS.GET, - "update": METHODS.PUT & "," & METHODS.PATCH, - "delete": METHODS.DELETE - }; - - /** - * Around handler for all actions it inherits - */ - function aroundHandler( - event, - rc, - prc, - targetAction, - eventArguments - ) { - try { - // start a resource timer - var stime = getTickCount(); - // prepare our response object - prc.response = getInstance( "Response@api" ); - // prepare argument execution - var args = { event: arguments.event, rc: arguments.rc, prc: arguments.prc }; - structAppend( args, arguments.eventArguments ); - // Incoming Format Detection - if ( !isNull( rc.format ) ) { - prc.response.setFormat( rc.format ); - } - // Execute action - var actionResults = arguments.targetAction( argumentCollection = args ); - } - // Auth Issues - catch ( "InvalidCredentials" e ) { - this.onAuthenticationFailure( argumentCollection = arguments ); - } - // Validation Exceptions - catch ( "ValidationException" e ) { - arguments.exception = e; - this.onValidationException( argumentCollection = arguments ); - } catch ( "EntityNotFound" e ) { - prc.response.setErrorMessage( e.message, 404 ); - - if ( listFindNoCase( "development,staging", getSetting( "environment" ) ) ) { - prc.response - .addMessage( "Detail: #e.detail#" ) - .addMessage( "StackTrace: #e.stacktrace#" ); - } - // Render Error Out - event.renderData( - type = prc.response.getFormat(), - data = prc.response.getDataPacket(), - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary() - ); - } catch ( Any e ) { - // Log Locally - log.error( - "Error calling #event.getCurrentEvent()#: #e.message# #e.detail#", - { "_stacktrace": e.stacktrace, "httpData": getHTTPRequestData() } - ); - // Setup General Error Response - prc.response - .setError( true ) - .addMessage( "General application error: #e.message#" ) - .setStatusCode( STATUS.INTERNAL_ERROR ) - .setStatusText( "General application error" ); - - // Development additions - if ( getSetting( "environment" ) eq "development" ) { - prc.response - .addMessage( "Detail: #e.detail#" ) - .addMessage( "StackTrace: #e.stacktrace#" ); - } - } - - // Development additions - if ( getSetting( "environment" ) eq "development" ) { - prc.response - .addHeader( "x-current-route", event.getCurrentRoute() ) - .addHeader( "x-current-routed-url", event.getCurrentRoutedURL() ) - .addHeader( "x-current-routed-namespace", event.getCurrentRoutedNamespace() ) - .addHeader( "x-current-event", event.getCurrentEvent() ); - } - // end timer - prc.response.setResponseTime( getTickCount() - stime ); - - // Did the controllers set a view to be rendered? If not use renderdata, else just delegate to view. - if ( - isNull( actionResults ) - AND - !event.getCurrentView().len() - AND - event.getRenderData().isEmpty() - ) { - // Get response data - var responseData = prc.response.getDataPacket(); - // If we have an error flag, render our messages and omit any marshalled data - if ( prc.response.getError() ) { - responseData = prc.response.getDataPacket(); - } - // Magical renderings - event.renderData( - type = prc.response.getFormat(), - data = responseData, - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary(), - jsonCallback = prc.response.getJsonCallback(), - jsonQueryFormat = prc.response.getJsonQueryFormat() - ); - } - - // Global Response Headers - prc.response - .addHeader( "x-response-time", prc.response.getResponseTime() ) - .addHeader( "x-cached-response", prc.response.getCachedResponse() ); - - // Response Headers - for ( var thisHeader in prc.response.getHeaders() ) { - event.setHTTPHeader( name = thisHeader.name, value = thisHeader.value ); - } - - // If results detected, just return them, controllers requesting to return results - if ( !isNull( actionResults ) ) { - return actionResults; - } - } - - /** - * on localized errors - */ - function onError( - event, - rc, - prc, - faultAction, - exception, - eventArguments - ) { - // Log Locally - log.error( - "Error in base handler (#arguments.faultAction#): #arguments.exception.message# #arguments.exception.detail#", - { "_stacktrace": arguments.exception.stacktrace, "httpData": getHTTPRequestData() } - ); - - // Verify response exists, else create one - if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getInstance( "Response@api" ); - } - - // Setup General Error Response - prc.response - .setError( true ) - .addMessage( "Base Handler Application Error: #arguments.exception.message#" ) - .setStatusCode( STATUS.INTERNAL_ERROR ) - .setStatusText( "General application error" ); - - // Development additions - if ( getSetting( "environment" ) eq "development" ) { - prc.response - .addMessage( "Detail: #arguments.exception.detail#" ) - .addMessage( "StackTrace: #arguments.exception.stacktrace#" ); - } - - // If in development, then it will show full trace error template, else render data - if ( getSetting( "environment" ) neq "development2" ) { - // Render Error Out - event.renderData( - type = prc.response.getFormat(), - data = prc.response.getDataPacket(), - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary() - ); - } - } - - /** - * on validation errors via cbValidation - */ - function onValidationException( - event, - rc, - prc, - eventArguments, - exception - ) { - // Log Locally - if ( log.canDebug() ) { - log.debug( - "ValidationException Execution of (#arguments.event.getCurrentEvent()#)", - arguments.exception.extendedInfo - ); - } - - var allErrors = deserializeJSON( exception.extendedInfo ).reduce( function( allErrors, field, fieldErrors ) { - arrayAppend( - allErrors, - fieldErrors.map( function( error ) { - return error.message; - } ), - true - ); - return allErrors; - }, [] ); - prc.response.setErrorMessage( allErrors, 412 ); - - // Render Error Out - event.renderData( - type = prc.response.getFormat(), - data = prc.response.getDataPacket(), - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary() - ); - } - - /** - * on invalid http verbs - */ - function onInvalidHTTPMethod( - event, - rc, - prc, - faultAction, - eventArguments - ) { - // Log Locally - log.warn( - "InvalidHTTPMethod Execution of (#arguments.faultAction#): #event.getHTTPMethod()#", - getHTTPRequestData() - ); - - // Setup Response - prc.response = getInstance( "Response@api" ) - .setError( true ) - .addMessage( "InvalidHTTPMethod Execution of (#arguments.faultAction#): #event.getHTTPMethod()#" ) - .setStatusCode( STATUS.NOT_ALLOWED ) - .setStatusText( "Invalid HTTP Method" ); - - // Render Error Out - event.renderData( - type = prc.response.getFormat(), - data = prc.response.getDataPacket(), - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary() - ); - } - - /** - * When missing actions are executed - */ - function onMissingAction( - event, - rc, - prc, - missingAction, - eventArguments - ) { - // Setup Response - prc.response = getInstance( "Response@api" ) - .setError( true ) - .addMessage( "Action '#arguments.missingAction#' could not be found" ) - .setStatusCode( STATUS.NOT_ALLOWED ) - .setStatusText( "Invalid Action" ); - - // Render Error Out - event.renderData( - type = prc.response.getFormat(), - data = prc.response.getDataPacket(), - contentType = prc.response.getContentType(), - statusCode = prc.response.getStatusCode(), - statusText = prc.response.getStatusText(), - location = prc.response.getLocation(), - isBinary = prc.response.getBinary() - ); - } - - /** - * Executed on authentication failures - */ - function onAuthenticationFailure( - event = getRequestContext(), - rc = getRequestCollection(), - prc = getPrivateCollection(), - abort = false - ) { - if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getInstance( "Response@api" ); - } - - // case when the a jwt token was valid, but expired - if ( - !isNull( prc.cbSecurity_validatorResults ) && - prc.cbSecurity_validatorResults.messages CONTAINS "expired" - ) { - prc.response - .setError( true ) - .setStatusCode( STATUS.NOT_AUTHENTICATED ) - .setStatusText( "Expired Authentication Credentials" ) - .addMessage( "Expired Authentication Credentials" ); - return; - } - - prc.response - .setError( true ) - .setStatusCode( STATUS.NOT_AUTHENTICATED ) - .setStatusText( "Invalid or Missing Credentials" ) - .addMessage( "Invalid or Missing Authentication Credentials" ); - } - - /** - * Executed on authorization failures - */ - function onAuthorizationFailure( - event = getRequestContext(), - rc = getRequestCollection(), - prc = getPrivateCollection(), - abort = false - ) { - if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getInstance( "Response@api" ); - } - - prc.response - .setError( true ) - .setStatusCode( STATUS.NOT_AUTHORIZED ) - .setStatusText( "Unauthorized Resource" ) - .addMessage( "Your permissions do not allow this operation" ); - - // Check for validator results - if ( !isNull( prc.cbSecurity_validatorResults ) ) { - prc.response.addMessage( prc.cbSecurity_validatorResults.messages ); - } - - /** - * When you need a really hard stop to prevent further execution ( use as last resort ) - */ - if ( arguments.abort ) { - event.setHTTPHeader( name = "Content-Type", value = "application/json" ); - - event.setHTTPHeader( statusCode = "#STATUS.NOT_AUTHORIZED#", statusText = "Not Authorized" ); - - writeOutput( serializeJSON( prc.response.getDataPacket() ) ); - - flush; - abort; - } - } - - /** - * Resource Not Found - */ - function onInvalidRoute( event, rc, prc ) { - if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getInstance( "Response@api" ); - } - - prc.response - .setError( true ) - .setStatusCode( STATUS.NOT_FOUND ) - .setStatusText( "Not Found" ) - .addMessage( "The resource requested (#event.getCurrentRoutedURL()#) could not be found" ); - } - - /**************************** RESTFUL UTILITIES ************************/ - - /** - * Utility method for when an expectation of the request failes ( e.g. an expected paramter is not provided ) - */ - private function onExpectationFailed( - event = getRequestContext(), - rc = getRequestCollection(), - prc = getRequestCollection( private = true ) - ) { - if ( !structKeyExists( prc, "Response" ) ) { - prc.response = getInstance( "Response@api" ); - } - - prc.response - .setError( true ) - .setStatusCode( STATUS.EXPECTATION_FAILED ) - .setStatusText( "Expectation Failed" ) - .addMessage( "An expectation for the request failed. Could not proceed" ); - } - -} diff --git a/modules_app/api/models/Response.cfc b/modules_app/api/models/Response.cfc deleted file mode 100644 index 18095c5..0000000 --- a/modules_app/api/models/Response.cfc +++ /dev/null @@ -1,217 +0,0 @@ -/** - * ******************************************************************************** - * Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp - * www.ortussolutions.com - * ******************************************************************************** - * HTTP Response model, spice up as needed and stored in the request scope - */ -component accessors="true" { - - property name="format" type="string" default="json"; - property name="data" type="any" default=""; - property name="error" type="boolean" default="false"; - property name="binary" type="boolean" default="false"; - property name="messages" type="array"; - property name="location" type="string" default=""; - property name="jsonCallback" type="string" default=""; - property - name="jsonQueryFormat" - type="string" - default="true" - hint="JSON Only: This parameter can be a Boolean value that specifies how to serialize ColdFusion queries or a string with possible values row, column, or struct"; - property name="contentType" type="string" default=""; - property name="statusCode" type="numeric" default="200"; - property name="statusText" type="string" default="OK"; - property name="responsetime" type="numeric" default="0"; - property name="cachedResponse" type="boolean" default="false"; - property name="headers" type="array"; - - /** - * Constructor - */ - Response function init() { - // Init properties - variables.format = "json"; - variables.data = {}; - variables.pagination = {}; - variables.error = false; - variables.binary = false; - variables.messages = []; - variables.location = ""; - variables.jsonCallBack = ""; - variables.jsonQueryFormat = "query"; - variables.contentType = ""; - variables.statusCode = 200; - variables.statusText = "OK"; - variables.responsetime = 0; - variables.cachedResponse = false; - variables.headers = []; - - return this; - } - - STATUS_TEXTS = { - "100": "Continue", - "101": "Switching Protocols", - "102": "Processing", - "200": "OK", - "201": "Created", - "202": "Accepted", - "203": "Non-authoritative Information", - "204": "No Content", - "205": "Reset Content", - "206": "Partial Content", - "207": "Multi-Status", - "208": "Already Reported", - "226": "IM Used", - "300": "Multiple Choices", - "301": "Moved Permanently", - "302": "Found", - "303": "See Other", - "304": "Not Modified", - "305": "Use Proxy", - "307": "Temporary Redirect", - "308": "Permanent Redirect", - "400": "Bad Request", - "401": "Unauthorized", - "402": "Payment Required", - "403": "Forbidden", - "404": "Not Found", - "405": "Method Not Allowed", - "406": "Not Acceptable", - "407": "Proxy Authentication Required", - "408": "Request Timeout", - "409": "Conflict", - "410": "Gone", - "411": "Length Required", - "412": "Precondition Failed", - "413": "Payload Too Large", - "414": "Request-URI Too Long", - "415": "Unsupported Media Type", - "416": "Requested Range Not Satisfiable", - "417": "Expectation Failed", - "418": "I'm a teapot", - "421": "Misdirected Request", - "422": "Unprocessable Entity", - "423": "Locked", - "424": "Failed Dependency", - "426": "Upgrade Required", - "428": "Precondition Required", - "429": "Too Many Requests", - "431": "Request Header Fields Too Large", - "444": "Connection Closed Without Response", - "451": "Unavailable For Legal Reasons", - "499": "Client Closed Request", - "500": "Internal Server Error", - "501": "Not Implemented", - "502": "Bad Gateway", - "503": "Service Unavailable", - "504": "Gateway Timeout", - "505": "HTTP Version Not Supported", - "506": "Variant Also Negotiates", - "507": "Insufficient Storage", - "508": "Loop Detected", - "510": "Not Extended", - "511": "Network Authentication Required", - "599": "Network Connect Timeout Error" - }; - - /** - * Sets the status code with a statusText for the API response - * @statusCode The status code to be set - * @statusText The status text to be set - * - * @return Returns the Response object for chaining - */ - function setStatusCode( required statusCode, statusText ) { - if ( isNull( arguments.statusText ) ) { - if ( structKeyExists( variables.STATUS_TEXTS, arguments.statusCode ) ) { - arguments.statusText = variables.STATUS_TEXTS[ arguments.statusCode ]; - } else { - arguments.statusText = ""; - } - } - variables.statusCode = arguments.statusCode; - variables.statusText = arguments.statusText; - return this; - } - - /** - * Sets the data and pagination from a struct with `results` and `pagination`. - * - * @data The struct containing both results and pagination. - * @resultsKey The name of the key with the results. - * @paginationKey The name of the key with the pagination. - */ - function setDataWithPagination( data, resultsKey = "results", paginationKey = "pagination" ) { - variables.data = arguments.data[ arguments.resultsKey ]; - variables.pagination = arguments.data[ arguments.paginationKey ]; - return this; - } - - /** - * Sets the error message with a code for the API response - * @errorMessage The errorMessage to be set - * @statusCode The status code to be set - * @statusText The status text to be set - * - * @return Returns the Response object for chaining - - */ - function setErrorMessage( required errorMessage, statusCode, statusText ) { - setError( true ); - addMessage( arguments.errorMessage ); - if ( !isNull( arguments.statusCode ) ) { - setStatusCode( arguments.statusCode, !isNull( arguments.statusText ) ? arguments.statusText : "" ); - } else { - if ( !isNull( arguments.statusText ) ) { - setStatusText( arguments.statusText ); - } - } - return this; - } - - - /** - * Add some messages - * @message Array or string of message to incorporate - */ - function addMessage( required any message ) { - if ( isSimpleValue( arguments.message ) ) { - arguments.message = [ arguments.message ]; - } - variables.messages.addAll( arguments.message ); - return this; - } - - /** - * Add a header - * @name The header name ( e.g. "Content-Type" ) - * @value The header value ( e.g. "application/json" ) - */ - function addHeader( required string name, required string value ) { - arrayAppend( variables.headers, { name: arguments.name, value: arguments.value } ); - return this; - } - - /** - * Returns a standard response formatted data packet - * @reset Reset the 'data' element of the original data packet - */ - function getDataPacket( boolean reset = false ) { - var packet = { - "error": variables.error ? true : false, - "messages": variables.messages, - "data": variables.data, - "pagination": variables.pagination - }; - - // Are we reseting the data packet - if ( arguments.reset ) { - packet.data = {}; - } - - return packet; - } - -} From 0009d47245cb2c5f443add8e1c6f632965e8522e Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 11:22:10 -0500 Subject: [PATCH 11/75] losts of ACF incompatibilities and coldbox 6 updates --- box.json | 8 +- .../api/modules_app/v1/ModuleConfig.cfc | 68 +------- .../api/modules_app/v1/handlers/Echo.cfc | 5 +- .../api/modules_app/v1/handlers/Rants.cfc | 7 +- .../api/modules_app/v1/models/RantService.cfc | 23 ++- .../api/modules_app/v2/handlers/Echo.cfc | 2 +- .../api/modules_app/v2/handlers/Rants.cfc | 2 +- .../api/modules_app/v3/handlers/Echo.cfc | 2 +- .../api/modules_app/v3/handlers/Rants.cfc | 2 +- .../api/modules_app/v4/handlers/Echo.cfc | 2 +- .../api/modules_app/v4/handlers/Rants.cfc | 2 +- .../api/modules_app/v5/handlers/Echo.cfc | 2 +- .../api/modules_app/v5/handlers/Rants.cfc | 2 +- .../api/modules_app/v6/handlers/Echo.cfc | 2 +- .../api/modules_app/v6/handlers/Rants.cfc | 2 +- tests/index.cfm | 2 +- tests/resources/BaseTest.cfc | 148 ++++++++++-------- tests/specs/integration/api-v1/RantsTest.cfc | 5 +- 18 files changed, 126 insertions(+), 160 deletions(-) diff --git a/box.json b/box.json index 62c05b5..e83ec50 100644 --- a/box.json +++ b/box.json @@ -48,7 +48,13 @@ "start:adobe":"server start serverConfigFile=server.json --force", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", - "format:check":"cfformat check modules_app/**/*.cfc,tests/specs/**/*.cfc --verbose" + "format:check":"cfformat check modules_app/**/*.cfc,tests/specs/**/*.cfc --verbose", + "test:v1" : "testbox run directory=tests/specs/integration/api-v1", + "test:v2" : "testbox run directory=tests/specs/integration/api-v2", + "test:v3" : "testbox run directory=tests/specs/integration/api-v3", + "test:v4" : "testbox run directory=tests/specs/integration/api-v4", + "test:v5" : "testbox run directory=tests/specs/integration/api-v5", + "test:v6" : "testbox run directory=tests/specs/integration/api-v6" }, "cfmigrations":{ "migrationsDirectory":"resources/database/migrations", diff --git a/modules_app/api/modules_app/v1/ModuleConfig.cfc b/modules_app/api/modules_app/v1/ModuleConfig.cfc index f6da326..93e8a6f 100644 --- a/modules_app/api/modules_app/v1/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v1/ModuleConfig.cfc @@ -1,45 +1,6 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * Module Config + */ component { // Module Properties @@ -48,10 +9,6 @@ component { this.webURL = ""; this.description = ""; this.version = "1.0.0"; - // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; - // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa - this.layoutParentLookup = true; // Module Entry Point this.entryPoint = "v1"; // Inherit entry point from parent, so this will be /api/v1 @@ -60,31 +17,10 @@ component { this.modelNamespace = "v1"; // CF Mapping this.cfmapping = "v1"; - // Auto-map models - this.autoMapModels = true; // Module Dependencies this.dependencies = []; function configure() { - // parent settings - parentSettings = {}; - - // module settings - stored in modules.name.settings - settings = {}; - - // Layout Settings - layoutSettings = { defaultLayout: "" }; - - // SES Routes: config/Router.cfc - - // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; - - // Custom Declared Interceptors - interceptors = []; - - // Binder Mappings - // binder.map("Alias").to("#moduleMapping#.model.MyService"); } /** diff --git a/modules_app/api/modules_app/v1/handlers/Echo.cfc b/modules_app/api/modules_app/v1/handlers/Echo.cfc index 22dbf27..b9b7066 100644 --- a/modules_app/api/modules_app/v1/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v1/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; @@ -18,7 +18,8 @@ component extends="api.handlers.BaseHandler" { * Index */ any function index( event, rc, prc ) { - prc.response.setData( "Welcome to my ColdBox RESTFul Service V1" ); + event.getResponse() + .setData( "Welcome to my ColdBox RESTFul Service V1" ); } } diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index 8c0a6ff..c93c5d5 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v1"; @@ -16,7 +16,6 @@ component extends="api.handlers.BaseHandler" { prc.response.setData( rants ); } - /** * Returns a single Rant * @@ -34,10 +33,10 @@ component extends="api.handlers.BaseHandler" { prc.response.addMessage( "rantID must be numeric" ); return; } - var rant = rantService.getRant( rc.rantID ) + var rant = rantService.getRant( rc.rantID ); if ( rant.len() ) { - prc.response.setData( deserializeJSON( serializeJSON( rant[ 1 ], "struct" ) ) ) + prc.response.setData( queryGetRow( rant, 1 ) ); } else { prc.response.setError( true ); prc.response.setStatusCode( 404 ); diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index 2c60a16..396883e 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -11,15 +11,14 @@ component singleton accessors="true" { } function list() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ); + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ); } function getRant( required numeric rantID ) { return queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } } ); } @@ -27,7 +26,7 @@ component singleton accessors="true" { queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, + { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, { result: "local.result" } ); return local.result; @@ -44,17 +43,17 @@ component singleton accessors="true" { modifiedDate = :modifiedDate ", { - body: { value: "#body#", type: "cf_sql_longvarchar" }, - userID: { value: "#userID#", type: "cf_sql_numeric" }, - createdDate: { value: "#now#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, + userID: { value: "#userID#", cfsqltype: "cf_sql_numeric" }, + createdDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" }, + modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } }, { result: "local.result" } ); return local.result; } - function update( required body, ) { + function update( required body, required numeric rantId ) { var now = now(); queryExecute( "update rants @@ -64,9 +63,9 @@ component singleton accessors="true" { where id = :rantID ", { - rantID: { value: "#rantID#", type: "cf_sql_integer" }, - body: { value: "#body#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + rantID: { value: "#rantID#", cfsqltype: "cf_sql_integer" }, + body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, + modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } }, { result: "local.result" } ); diff --git a/modules_app/api/modules_app/v2/handlers/Echo.cfc b/modules_app/api/modules_app/v2/handlers/Echo.cfc index 8fcbbac..ce7dbac 100644 --- a/modules_app/api/modules_app/v2/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v2/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; diff --git a/modules_app/api/modules_app/v2/handlers/Rants.cfc b/modules_app/api/modules_app/v2/handlers/Rants.cfc index 0a30b42..7a9d6a2 100644 --- a/modules_app/api/modules_app/v2/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v2/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v2"; diff --git a/modules_app/api/modules_app/v3/handlers/Echo.cfc b/modules_app/api/modules_app/v3/handlers/Echo.cfc index cd27f45..c1df173 100644 --- a/modules_app/api/modules_app/v3/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v3/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 14e86ee..49e850a 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v3"; diff --git a/modules_app/api/modules_app/v4/handlers/Echo.cfc b/modules_app/api/modules_app/v4/handlers/Echo.cfc index c4e04b5..fa5d0a1 100644 --- a/modules_app/api/modules_app/v4/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v4/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index e0cc68d..30c76c6 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v4"; diff --git a/modules_app/api/modules_app/v5/handlers/Echo.cfc b/modules_app/api/modules_app/v5/handlers/Echo.cfc index 8335b5d..0259388 100644 --- a/modules_app/api/modules_app/v5/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v5/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index 21591e9..8aba29a 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v5"; diff --git a/modules_app/api/modules_app/v6/handlers/Echo.cfc b/modules_app/api/modules_app/v6/handlers/Echo.cfc index 1683255..1296b45 100644 --- a/modules_app/api/modules_app/v6/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v6/handlers/Echo.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Event Handler which inherits from the module `api` */ -component extends="api.handlers.BaseHandler" { +component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES this.prehandler_only = ""; diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index a969293..c1f911a 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -1,7 +1,7 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component displayName="Rants" extends="api.handlers.BaseHandler" { +component displayName="Rants" extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v6"; diff --git a/tests/index.cfm b/tests/index.cfm index bb665cd..0ccfa80 100644 --- a/tests/index.cfm +++ b/tests/index.cfm @@ -2,7 +2,7 @@ - + diff --git a/tests/resources/BaseTest.cfc b/tests/resources/BaseTest.cfc index 05c688c..6dcd213 100644 --- a/tests/resources/BaseTest.cfc +++ b/tests/resources/BaseTest.cfc @@ -5,61 +5,16 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { /*********************************** LIFE CYCLE Methods ***********************************/ - // executes before all suites+specs in the run() method + /** + * executes before all suites+specs in the run() method + */ function beforeAll(){ super.beforeAll(); - var lengthTest = function( expectation, args = {} ) { - // handle both positional and named arguments - param args.value = ""; - if ( structKeyExists( args, 1 ) ) { - args.value = args[ 1 ]; - } - - param args.message = ""; - if ( structKeyExists( args, 2 ) ) { - args.message = args[ 2 ]; - } - - param args.operator = "GT"; - if ( structKeyExists( args, 3 ) ) { - args.value = args[ 3 ]; - } - - if ( !isNumeric( args.value )) { - expectation.message = "The value you are testing must be a valid number"; - return false; - } - try{ - var length = expectation.actual.len(); - } catch ( any e ){ - expectation.message = "The length of the Item could not be found"; - return false; - } - - if( args.operator == "GT" && length <= args.value ){ - expectation.message = "The length of the item was #length# - that is not GT #args.value#"; - debug( expectation.actual ); - return false; - } else if( args.operator == "GTE" && length < args.value ){ - expectation.message = "The length of the item was #length# - that is not GTE #args.value#"; - debug( expectation.actual ); - return false; - } else if( args.operator == "LT" && length >= args.value ){ - expectation.message = "The length of the item was #length# - that is not LT #args.value#"; - debug( expectation.actual ); - return false; - } else if( args.operator == "LTE" && length > args.value ){ - expectation.message = "The length of the item was #length# - that is not LTE #args.value#"; - debug( expectation.actual ); - return false; - } - - return true; - }; + var lengthTest = addMatchers( { - toHaveStatusCode: function( expectation, args = {} ) { + toHaveStatusCode : function( expectation, args = {} ) { // handle both positional and named arguments param args.statusCode = ""; if ( structKeyExists( args, 1 ) ) { @@ -92,7 +47,8 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { return true; }, - toHaveKeyWithCase: function( expectation, args = {} ) { + + toHaveKeyWithCase : function( expectation, args = {} ) { // handle both positional and named arguments param args.key = ""; if ( structKeyExists( args, 1 ) ) { @@ -120,36 +76,104 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { return true; }, - toHaveLengthGT: function( expectation, args = {}, lengthTest=lengthTest ) { + + toHaveLengthGT : function( expectation, args = {}, lengthTest=variables.lengthTest ) { args[ "operator" ] = "GT"; - return lengthTest( expectation, args ); + return arguments.lengthTest( expectation, args ); }, - toHaveLengthGTE: function( expectation, args = {}, lengthTest=lengthTest ) { + + toHaveLengthGTE : function( expectation, args = {}, lengthTest=variables.lengthTest ) { args[ "operator" ] = "GTE"; - return lengthTest( expectation, args ); + return arguments.lengthTest( expectation, args ); }, - toHaveLengthLT: function( expectation, args = {}, lengthTest=lengthTest ) { + + toHaveLengthLT : function( expectation, args = {}, lengthTest=variables.lengthTest ) { args[ "operator" ] = "LT"; - return lengthTest( expectation, args ); + return arguments.lengthTest( expectation, args ); }, - toHaveLengthLTE: function( expectation, args = {}, lengthTest=lengthTest ) { + + toHaveLengthLTE : function( expectation, args = {}, lengthTest=variables.lengthTest ) { args[ "operator" ] = "LTE"; - return lengthTest( expectation, args ); - }, - } ); + return arguments.lengthTest( expectation, args ); + } + } ); + getWireBox().autowire( this ); } - // executes after all suites+specs in the run() method + /** + * A length test + */ + private function lengthTest( expectation, args = {} ) { + // handle both positional and named arguments + param args.value = ""; + if ( structKeyExists( args, 1 ) ) { + args.value = args[ 1 ]; + } + + param args.message = ""; + if ( structKeyExists( args, 2 ) ) { + args.message = args[ 2 ]; + } + + param args.operator = "GT"; + if ( structKeyExists( args, 3 ) ) { + args.value = args[ 3 ]; + } + + if ( !isNumeric( args.value )) { + expectation.message = "The value you are testing must be a valid number"; + return false; + } + try{ + var length = expectation.actual.len(); + } catch ( any e ){ + expectation.message = "The length of the Item could not be found"; + return false; + } + + if( args.operator == "GT" && length <= args.value ){ + expectation.message = "The length of the item was #length# - that is not GT #args.value#"; + debug( expectation.actual ); + return false; + } else if( args.operator == "GTE" && length < args.value ){ + expectation.message = "The length of the item was #length# - that is not GTE #args.value#"; + debug( expectation.actual ); + return false; + } else if( args.operator == "LT" && length >= args.value ){ + expectation.message = "The length of the item was #length# - that is not LT #args.value#"; + debug( expectation.actual ); + return false; + } else if( args.operator == "LTE" && length > args.value ){ + expectation.message = "The length of the item was #length# - that is not LTE #args.value#"; + debug( expectation.actual ); + return false; + } + + return true; + }; + + /** + * executes after all suites+specs in the run() method + */ function afterAll(){ super.afterAll(); } + /** + * Custom test reset + */ function reset(){ structDelete( application, "wirebox" ); structDelete( application, "cbController" ); } + /** + * Rollback all testing, called by TestBox for me + * + * @spec The spec in test + * @suite The suite in test + */ function withRollback( spec, suite ) aroundEach { transaction{ try{ diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index d8f9663..5c351db 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -13,6 +13,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { then( "I will get a list of Rants", function() { var event = get( "/api/v1/rants/list" ); var returnedJSON = event.getRenderData().data; + expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); // expect( returnedJSON ).toHaveKey( "error" ); @@ -22,7 +23,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON.data ).toBeArray(); + expect( returnedJSON.data ).toBeQuery(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); } ); @@ -83,7 +84,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( event ).toHaveStatusCode( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); expect( returnedJSON.data.id ).toBe( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); From b1e873dbfcbdc93c4c43348e8d39ea340422f26b Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 11:22:58 -0500 Subject: [PATCH 12/75] finalized v1 --- modules_app/api/modules_app/v1/models/UserService.cfc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules_app/api/modules_app/v1/models/UserService.cfc b/modules_app/api/modules_app/v1/models/UserService.cfc index 9cd44a9..ebe274e 100644 --- a/modules_app/api/modules_app/v1/models/UserService.cfc +++ b/modules_app/api/modules_app/v1/models/UserService.cfc @@ -14,8 +14,7 @@ component singleton accessors="true" { return queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { userID: { value: "#userID#", type: "cf_sql_numeric" } } ); } From d3989aa49a194c2d90e3d0e71fd7937bd64e2489 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 11:28:07 -0500 Subject: [PATCH 13/75] reverted engines due to compilation bugs on latest hotfixes of 2018 --- .../api/modules_app/v1/ModuleConfig.cfc | 4 -- .../api/modules_app/v2/ModuleConfig.cfc | 72 +------------------ server.json | 2 +- 3 files changed, 3 insertions(+), 75 deletions(-) diff --git a/modules_app/api/modules_app/v1/ModuleConfig.cfc b/modules_app/api/modules_app/v1/ModuleConfig.cfc index 93e8a6f..fc230e0 100644 --- a/modules_app/api/modules_app/v1/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v1/ModuleConfig.cfc @@ -5,10 +5,6 @@ component { // Module Properties this.title = "v1"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; // Module Entry Point this.entryPoint = "v1"; // Inherit entry point from parent, so this will be /api/v1 diff --git a/modules_app/api/modules_app/v2/ModuleConfig.cfc b/modules_app/api/modules_app/v2/ModuleConfig.cfc index 3708393..8be8ad1 100644 --- a/modules_app/api/modules_app/v2/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v2/ModuleConfig.cfc @@ -1,57 +1,10 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * Module Config + */ component { // Module Properties this.title = "v2"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; - // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; - // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa - this.layoutParentLookup = true; // Module Entry Point this.entryPoint = "v2"; // Inherit entry point from parent, so this will be /api/v1 @@ -60,31 +13,10 @@ component { this.modelNamespace = "v2"; // CF Mapping this.cfmapping = "v2"; - // Auto-map models - this.autoMapModels = true; // Module Dependencies this.dependencies = []; function configure() { - // parent settings - parentSettings = {}; - - // module settings - stored in modules.name.settings - settings = {}; - - // Layout Settings - layoutSettings = { defaultLayout: "" }; - - // SES Routes: config/Router.cfc - - // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; - - // Custom Declared Interceptors - interceptors = []; - - // Binder Mappings - // binder.map("Alias").to("#moduleMapping#.model.MyService"); } /** diff --git a/server.json b/server.json index ac432e4..61f6825 100644 --- a/server.json +++ b/server.json @@ -1,7 +1,7 @@ { "app":{ "serverHomeDirectory":".engine/adobe2018", - "cfengine":"adobe@2018" + "cfengine":"adobe@2018.0.7" }, "web":{ "directoryBrowsing":true, From fa50ae7bc39d4d41f1cb0ff2511a1235be1bacb9 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 11:54:44 -0500 Subject: [PATCH 14/75] v2 finalized --- Application.cfc | 5 +++ .../api/modules_app/v2/handlers/Rants.cfc | 9 ++--- .../api/modules_app/v2/models/RantService.cfc | 38 +++++++++++-------- .../api/modules_app/v2/models/UserService.cfc | 8 ++-- tests/specs/integration/api-v2/RantsTest.cfc | 2 +- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Application.cfc b/Application.cfc index 1396417..ca66bbe 100644 --- a/Application.cfc +++ b/Application.cfc @@ -10,6 +10,11 @@ component{ this.sessionTimeout = createTimeSpan(0,0,30,0); this.setClientCookies = true; this.datasource = "fluentAPI"; + + // Important + this.serialization.preserveCaseForStructKey = true; + this.serialization.preserveCaseForQueryColumn = true; + // COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); // The web server mapping to this application. Used for remote purposes or static purposes diff --git a/modules_app/api/modules_app/v2/handlers/Rants.cfc b/modules_app/api/modules_app/v2/handlers/Rants.cfc index 7a9d6a2..844318a 100644 --- a/modules_app/api/modules_app/v2/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v2/handlers/Rants.cfc @@ -7,7 +7,6 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v2"; property name="userService" inject="UserService@v2"; - /** * Returns a list of Rants */ @@ -15,7 +14,6 @@ component extends="coldbox.system.RestHandler" { prc.response.setData( rantService.list() ); } - /** * Returns a single Rant * @@ -26,9 +24,10 @@ component extends="coldbox.system.RestHandler" { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; } - var rant = rantService.get( rc.rantID ) - if ( rant.len() ) { - prc.response.setData( deserializeJSON( serializeJSON( rant[ 1 ], "struct" ) ) ) + var rant = rantService.get( rc.rantID ); + + if ( !rant.isEmpty() ) { + prc.response.setData( rant ) } else { prc.response.setErrorMessage( "Error loading Rant - Rant not found", 404 ); } diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index babfd51..b4d9433 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -10,24 +10,30 @@ component singleton accessors="true" { return this; } - function list() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ); + array function list() { + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ) + .reduce( (result, row) => { + result.append( row ); + return result; + }, [] ); } - function get( required numeric rantID ) { + struct function get( required numeric rantID ) { return queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } - ); + { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } } + ) + .reduce( (result, row) => { + return row; + }, {} ); } function delete( required numeric rantID ) { queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, + { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, { result: "local.result" } ); return local.result; @@ -44,17 +50,17 @@ component singleton accessors="true" { modifiedDate = :modifiedDate ", { - body: { value: "#body#", type: "cf_sql_longvarchar" }, - userID: { value: "#userID#", type: "cf_sql_numeric" }, - createdDate: { value: "#now#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, + userID: { value: "#userID#", cfsqltype: "cf_sql_numeric" }, + createdDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" }, + modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } }, { result: "local.result" } ); return local.result; } - function update( required body, ) { + function update( required body, required rantId ) { var now = now(); queryExecute( "update rants @@ -64,9 +70,9 @@ component singleton accessors="true" { where id = :rantID ", { - rantID: { value: "#rantID#", type: "cf_sql_integer" }, - body: { value: "#body#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + rantID: { value: "#rantID#", cfsqltype: "cf_sql_integer" }, + body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, + modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } }, { result: "local.result" } ); @@ -78,7 +84,7 @@ component singleton accessors="true" { queryExecute( "select id from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, + { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, { returntype: "array" } ).len() ) diff --git a/modules_app/api/modules_app/v2/models/UserService.cfc b/modules_app/api/modules_app/v2/models/UserService.cfc index d56aea6..c0e3499 100644 --- a/modules_app/api/modules_app/v2/models/UserService.cfc +++ b/modules_app/api/modules_app/v2/models/UserService.cfc @@ -14,9 +14,11 @@ component singleton accessors="true" { return queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } - ); + { userID: { value: "#userID#", type: "cf_sql_numeric" } } + ).reduce( (result, row) => { + result.append( row ); + return result; + }, [] ); } boolean function exists( required numeric userID ) { diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 785f816..0a01b9a 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -73,7 +73,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( event ).toHaveStatusCode( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); expect( returnedJSON.data.id ).toBe( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); From acd441e0a51c344aff8c7980899ef1f6a267dd42 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 May 2020 12:12:35 -0500 Subject: [PATCH 15/75] v3 finalized for acf compat --- .../api/modules_app/v1/ModuleConfig.cfc | 16 +-- .../api/modules_app/v1/config/Router.cfc | 2 +- .../api/modules_app/v1/handlers/Echo.cfc | 15 ++- .../api/modules_app/v1/handlers/Rants.cfc | 18 +-- .../api/modules_app/v1/models/RantService.cfc | 77 +++++++++---- .../api/modules_app/v1/models/UserService.cfc | 11 +- .../api/modules_app/v2/ModuleConfig.cfc | 16 +-- .../api/modules_app/v2/config/Router.cfc | 2 +- .../api/modules_app/v2/handlers/Echo.cfc | 12 +- .../api/modules_app/v2/handlers/Rants.cfc | 43 +++++--- .../api/modules_app/v2/models/RantService.cfc | 100 +++++++++++------ .../api/modules_app/v2/models/UserService.cfc | 24 ++-- .../api/modules_app/v3/ModuleConfig.cfc | 88 ++------------- .../api/modules_app/v3/config/Router.cfc | 8 +- .../api/modules_app/v3/handlers/Echo.cfc | 12 +- .../api/modules_app/v3/handlers/Rants.cfc | 45 ++++---- .../api/modules_app/v3/models/BaseService.cfc | 23 ++-- .../api/modules_app/v3/models/RantService.cfc | 103 +++++++++++++----- .../api/modules_app/v3/models/UserService.cfc | 25 +++-- .../api/modules_app/v4/ModuleConfig.cfc | 52 ++++----- .../api/modules_app/v4/config/Router.cfc | 8 +- .../api/modules_app/v4/handlers/Echo.cfc | 12 +- .../api/modules_app/v4/handlers/Rants.cfc | 50 +++++---- .../api/modules_app/v4/models/BaseService.cfc | 21 ++-- .../api/modules_app/v4/models/Rant.cfc | 26 ++--- .../api/modules_app/v4/models/RantService.cfc | 103 ++++++++++++------ .../api/modules_app/v4/models/UserService.cfc | 25 +++-- .../api/modules_app/v5/ModuleConfig.cfc | 52 ++++----- .../api/modules_app/v5/config/Router.cfc | 8 +- .../api/modules_app/v5/handlers/Echo.cfc | 12 +- .../api/modules_app/v5/handlers/Rants.cfc | 46 ++++---- .../api/modules_app/v5/models/BaseEntity.cfc | 62 +++++------ .../api/modules_app/v5/models/BaseService.cfc | 23 ++-- .../api/modules_app/v5/models/Rant.cfc | 12 +- .../api/modules_app/v5/models/RantService.cfc | 103 ++++++++++++------ .../api/modules_app/v5/models/UserService.cfc | 25 +++-- .../api/modules_app/v6/ModuleConfig.cfc | 52 ++++----- .../api/modules_app/v6/config/Router.cfc | 8 +- .../api/modules_app/v6/handlers/Echo.cfc | 12 +- .../api/modules_app/v6/handlers/Rants.cfc | 28 ++--- .../api/modules_app/v6/models/BaseEntity.cfc | 62 +++++------ .../api/modules_app/v6/models/BaseService.cfc | 27 +++-- .../api/modules_app/v6/models/Rant.cfc | 17 +-- .../api/modules_app/v6/models/RantService.cfc | 103 ++++++++++++------ .../api/modules_app/v6/models/UserService.cfc | 25 +++-- tests/specs/integration/api-v3/RantsTest.cfc | 88 ++++++--------- 46 files changed, 981 insertions(+), 721 deletions(-) diff --git a/modules_app/api/modules_app/v1/ModuleConfig.cfc b/modules_app/api/modules_app/v1/ModuleConfig.cfc index fc230e0..9232950 100644 --- a/modules_app/api/modules_app/v1/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v1/ModuleConfig.cfc @@ -4,31 +4,31 @@ component { // Module Properties - this.title = "v1"; + this.title = "v1"; // Module Entry Point - this.entryPoint = "v1"; + this.entryPoint = "v1"; // Inherit entry point from parent, so this will be /api/v1 this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v1"; + this.modelNamespace = "v1"; // CF Mapping - this.cfmapping = "v1"; + this.cfmapping = "v1"; // Module Dependencies - this.dependencies = []; + this.dependencies = []; - function configure() { + function configure(){ } /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v1/config/Router.cfc b/modules_app/api/modules_app/v1/config/Router.cfc index 574a9e4..4cc65e3 100644 --- a/modules_app/api/modules_app/v1/config/Router.cfc +++ b/modules_app/api/modules_app/v1/config/Router.cfc @@ -1,6 +1,6 @@ component { - function configure() { + function configure(){ route( "/", "echo.index" ); route( "/:handler/:action" ).end(); } diff --git a/modules_app/api/modules_app/v1/handlers/Echo.cfc b/modules_app/api/modules_app/v1/handlers/Echo.cfc index b9b7066..688a4c4 100644 --- a/modules_app/api/modules_app/v1/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v1/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,9 +17,8 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { - event.getResponse() - .setData( "Welcome to my ColdBox RESTFul Service V1" ); + any function index( event, rc, prc ){ + event.getResponse().setData( "Welcome to my ColdBox RESTFul Service V1" ); } } diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index c93c5d5..28e9a9e 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -11,7 +11,7 @@ component extends="coldbox.system.RestHandler" { /** * Returns a list of Rants */ - any function list( event, rc, prc ) { + any function list( event, rc, prc ){ var rants = rantService.list(); prc.response.setData( rants ); } @@ -20,7 +20,7 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant * */ - function view( event, rc, prc ) { + function view( event, rc, prc ){ if ( !structKeyExists( rc, "rantID" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); @@ -48,7 +48,7 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant * */ - function delete( event, rc, prc ) { + function delete( event, rc, prc ){ if ( !structKeyExists( rc, "rantID" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); @@ -73,7 +73,7 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant * */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ if ( !structKeyExists( rc, "body" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); @@ -107,7 +107,7 @@ component extends="coldbox.system.RestHandler" { } var result = rantService.create( body = rc.body, userID = rc.userID ); if ( result.recordcount ) { - prc.response.setData( { "rantID": result.generatedKey } ); + prc.response.setData( { "rantID" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); return; } else { @@ -122,7 +122,7 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant * */ - function save( event, rc, prc ) { + function save( event, rc, prc ){ if ( !structKeyExists( rc, "body" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); @@ -173,7 +173,11 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "User not found" ); return; } - var result = rantService.update( body = rc.body, userID = rc.userID, rantID = rc.rantID ); + var result = rantService.update( + body = rc.body, + userID = rc.userID, + rantID = rc.rantID + ); if ( result.recordcount ) { prc.response.addMessage( "Rant Updated" ); } else { diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index 396883e..944b58c 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -6,68 +6,99 @@ component singleton accessors="true" { /** * Constructor */ - RantService function init() { + RantService function init(){ return this; } - function list() { + function list(){ return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ); } - function getRant( required numeric rantID ) { + function getRant( required numeric rantID ){ return queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } } + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + } ); } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required body, required numeric userID ) { + function create( required body, required numeric userID ){ var now = now(); queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, - userID: { value: "#userID#", cfsqltype: "cf_sql_numeric" }, - createdDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" }, - modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + userID : { + value : "#userID#", + cfsqltype : "cf_sql_numeric" + }, + createdDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } - function update( required body, required numeric rantId ) { + function update( required body, required numeric rantId ){ var now = now(); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#rantID#", cfsqltype: "cf_sql_integer" }, - body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, - modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_integer" + }, + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } diff --git a/modules_app/api/modules_app/v1/models/UserService.cfc b/modules_app/api/modules_app/v1/models/UserService.cfc index ebe274e..cbda85f 100644 --- a/modules_app/api/modules_app/v1/models/UserService.cfc +++ b/modules_app/api/modules_app/v1/models/UserService.cfc @@ -6,15 +6,20 @@ component singleton accessors="true" { /** * Constructor */ - UserService function init() { + UserService function init(){ return this; } - function get( required numeric userID ) { + function get( required numeric userID ){ return queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + } ); } diff --git a/modules_app/api/modules_app/v2/ModuleConfig.cfc b/modules_app/api/modules_app/v2/ModuleConfig.cfc index 8be8ad1..67fbf00 100644 --- a/modules_app/api/modules_app/v2/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v2/ModuleConfig.cfc @@ -4,31 +4,31 @@ component { // Module Properties - this.title = "v2"; + this.title = "v2"; // Module Entry Point - this.entryPoint = "v2"; + this.entryPoint = "v2"; // Inherit entry point from parent, so this will be /api/v1 this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v2"; + this.modelNamespace = "v2"; // CF Mapping - this.cfmapping = "v2"; + this.cfmapping = "v2"; // Module Dependencies - this.dependencies = []; + this.dependencies = []; - function configure() { + function configure(){ } /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v2/config/Router.cfc b/modules_app/api/modules_app/v2/config/Router.cfc index 328adc6..98d3791 100644 --- a/modules_app/api/modules_app/v2/config/Router.cfc +++ b/modules_app/api/modules_app/v2/config/Router.cfc @@ -1,6 +1,6 @@ component { - function configure() { + function configure(){ post( "/rants/create", "rants.create" ) route( "/rants/:rantID/delete", "rants.delete" ) route( "/rants/:rantID/save", "rants.save" ) diff --git a/modules_app/api/modules_app/v2/handlers/Echo.cfc b/modules_app/api/modules_app/v2/handlers/Echo.cfc index ce7dbac..9e9f6d9 100644 --- a/modules_app/api/modules_app/v2/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v2/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,7 +17,7 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( "Welcome to my ColdBox RESTFul Service V2" ); } diff --git a/modules_app/api/modules_app/v2/handlers/Rants.cfc b/modules_app/api/modules_app/v2/handlers/Rants.cfc index 844318a..9e8975c 100644 --- a/modules_app/api/modules_app/v2/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v2/handlers/Rants.cfc @@ -10,7 +10,7 @@ component extends="coldbox.system.RestHandler" { /** * Returns a list of Rants */ - any function list( event, rc, prc ) { + any function list( event, rc, prc ){ prc.response.setData( rantService.list() ); } @@ -18,8 +18,11 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant * */ - function view( event, rc, prc ) { - var validationResults = validate( target = rc, constraints = { rantID: { required: true, type: "numeric" } } ); + function view( event, rc, prc ){ + var validationResults = validate( + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } + ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; @@ -37,8 +40,11 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant * */ - function delete( event, rc, prc ) { - var validationResults = validate( target = rc, constraints = { rantID: { required: true, type: "numeric" } } ); + function delete( event, rc, prc ){ + var validationResults = validate( + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } + ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; @@ -56,10 +62,13 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant * */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ var validationResults = validate( - target = rc, - constraints = { userID: { required: true, type: "numeric" }, body: { required: true } } + target = rc, + constraints = { + userID : { required : true, type : "numeric" }, + body : { required : true } + } ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); @@ -71,7 +80,7 @@ component extends="coldbox.system.RestHandler" { } var result = rantService.create( body = rc.body, userID = rc.userID ); if ( result.recordcount ) { - prc.response.setData( { "rantID": result.generatedKey } ); + prc.response.setData( { "rantID" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); return; } else { @@ -84,13 +93,13 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant * */ - function save( event, rc, prc ) { + function save( event, rc, prc ){ var validationResults = validate( - target = rc, + target = rc, constraints = { - rantID: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + rantID : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ); if ( validationResults.hasErrors() ) { @@ -106,7 +115,11 @@ component extends="coldbox.system.RestHandler" { prc.response.setErrorMessage( "User not found", 404 ); return; } - var result = rantService.update( body = rc.body, userID = rc.userID, rantID = rc.rantID ); + var result = rantService.update( + body = rc.body, + userID = rc.userID, + rantID = rc.rantID + ); if ( result.recordcount ) { prc.response.addMessage( "Rant Updated" ); } else { diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index b4d9433..ef55a82 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -6,86 +6,120 @@ component singleton accessors="true" { /** * Constructor */ - RantService function init() { + RantService function init(){ return this; } - array function list() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ) - .reduce( (result, row) => { - result.append( row ); - return result; - }, [] ); + array function list(){ + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } - struct function get( required numeric rantID ) { + struct function get( required numeric rantID ){ return queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } } - ) - .reduce( (result, row) => { + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + } + ).reduce( ( result, row ) => { return row; }, {} ); } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required body, required numeric userID ) { + function create( required body, required numeric userID ){ var now = now(); queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, - userID: { value: "#userID#", cfsqltype: "cf_sql_numeric" }, - createdDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" }, - modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + userID : { + value : "#userID#", + cfsqltype : "cf_sql_numeric" + }, + createdDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } - function update( required body, required rantId ) { + function update( required body, required rantId ){ var now = now(); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#rantID#", cfsqltype: "cf_sql_integer" }, - body: { value: "#body#", cfsqltype: "cf_sql_longvarchar" }, - modifiedDate: { value: "#now#", cfsqltype: "cf_sql_timestamp" } + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_integer" + }, + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } - boolean function exists( required numeric rantID ) { + boolean function exists( required numeric rantID ){ return booleanFormat( queryExecute( "select id from rants where id = :rantID", - { rantID: { value: "#rantID#", cfsqltype: "cf_sql_numeric" } }, - { returntype: "array" } + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } diff --git a/modules_app/api/modules_app/v2/models/UserService.cfc b/modules_app/api/modules_app/v2/models/UserService.cfc index c0e3499..c87ef02 100644 --- a/modules_app/api/modules_app/v2/models/UserService.cfc +++ b/modules_app/api/modules_app/v2/models/UserService.cfc @@ -6,28 +6,38 @@ component singleton accessors="true" { /** * Constructor */ - UserService function init() { + UserService function init(){ return this; } - function get( required numeric userID ) { + function get( required numeric userID ){ return queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } } - ).reduce( (result, row) => { + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + } + ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); } - boolean function exists( required numeric userID ) { + boolean function exists( required numeric userID ){ return booleanFormat( queryExecute( "select id from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } diff --git a/modules_app/api/modules_app/v3/ModuleConfig.cfc b/modules_app/api/modules_app/v3/ModuleConfig.cfc index 9ef25e3..721390c 100644 --- a/modules_app/api/modules_app/v3/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v3/ModuleConfig.cfc @@ -1,102 +1,34 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * Module Config + */ component { // Module Properties - this.title = "v3"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; - // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; - // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa - this.layoutParentLookup = true; + this.title = "v3"; // Module Entry Point - this.entryPoint = "v3"; + this.entryPoint = "v3"; // Inherit entry point from parent, so this will be /api/v1 this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v3"; + this.modelNamespace = "v3"; // CF Mapping - this.cfmapping = "v3"; - // Auto-map models - this.autoMapModels = true; + this.cfmapping = "v3"; // Module Dependencies - this.dependencies = []; - - function configure() { - // parent settings - parentSettings = {}; - - // module settings - stored in modules.name.settings - settings = {}; - - // Layout Settings - layoutSettings = { defaultLayout: "" }; - - // SES Routes: config/Router.cfc - - // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; - - // Custom Declared Interceptors - interceptors = []; + this.dependencies = []; - // Binder Mappings - // binder.map("Alias").to("#moduleMapping#.model.MyService"); + function configure(){ } /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v3/config/Router.cfc b/modules_app/api/modules_app/v3/config/Router.cfc index c5fcf6b..da45da4 100644 --- a/modules_app/api/modules_app/v3/config/Router.cfc +++ b/modules_app/api/modules_app/v3/config/Router.cfc @@ -1,7 +1,11 @@ component { - function configure() { - resources( resource = "rants", parameterName = "rantID", except = [ "new", "edit" ] ); + function configure(){ + resources( + resource = "rants", + parameterName = "rantID", + except = [ "new", "edit" ] + ); route( "/", "echo.index" ); route( "/:handler/:action" ).end(); diff --git a/modules_app/api/modules_app/v3/handlers/Echo.cfc b/modules_app/api/modules_app/v3/handlers/Echo.cfc index c1df173..1488f19 100644 --- a/modules_app/api/modules_app/v3/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v3/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,7 +17,7 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( "Welcome to my ColdBox RESTFul Service v3" ); } diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 49e850a..68dea36 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -11,7 +11,7 @@ component extends="coldbox.system.RestHandler" { /** * Returns a list of Rants */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( rantService.list() ); } @@ -19,24 +19,24 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant * */ - function show( event, rc, prc ) { + function show( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); prc.response.setData( - deserializeJSON( serializeJSON( rantService.getOrFail( rc.rantID )[ 1 ], "struct" ) ) - ) + rantService.getOrFail( rc.rantID ) + ); } /** * Deletes a single Rant * */ - function delete( event, rc, prc ) { + function delete( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); rantService.existsOrFail( rc.rantID ) var result = rantService.delete( rc.rantID ); @@ -47,15 +47,18 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant * */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { userID: { required: true, type: "numeric" }, body: { required: true } } + target = rc, + constraints = { + userID : { required : true, type : "numeric" }, + body : { required : true } + } ); userService.existsOrFail( rc.userID ); var result = rantService.create( body = rc.body, userID = rc.userID ); if ( result.recordcount ) { - prc.response.setData( { "rantID": result.generatedKey } ); + prc.response.setData( { "rantID" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); return; } @@ -65,20 +68,24 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant * */ - function update( event, rc, prc ) { + function update( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, + target = rc, constraints = { - rantID: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + rantID : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ); rantService.existsOrFail( rc.rantID ); userService.existsOrFail( rc.userID ); - var result = rantService.update( body = rc.body, userID = rc.userID, rantID = rc.rantID ); + var result = rantService.update( + body = rc.body, + userID = rc.userID, + rantID = rc.rantID + ); if ( result.recordcount ) { prc.response.addMessage( "Rant Updated" ); } diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index a282fd4..71273e9 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -13,11 +13,11 @@ component accessors="true" { function init( entityName, tableName, - primaryKey = "id", + primaryKey = "id", // parameterName="", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); @@ -39,13 +39,18 @@ component accessors="true" { * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists() { + boolean function exists(){ return booleanFormat( queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { id: { value: arguments[ 1 ], type: "cf_sql_numeric" } }, - { returntype: "array" } + { + id : { + value : arguments[ 1 ], + cfsqltype : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } @@ -56,7 +61,7 @@ component accessors="true" { * @return Returns true if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function existsOrFail() { + function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } else { @@ -70,9 +75,9 @@ component accessors="true" { * @return Returns the Entity if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function getOrFail() { + function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); - if ( !maybeEntity.len() ) { + if ( maybeEntity.isEmpty() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; diff --git a/modules_app/api/modules_app/v3/models/RantService.cfc b/modules_app/api/modules_app/v3/models/RantService.cfc index 2229a0f..1f2832b 100644 --- a/modules_app/api/modules_app/v3/models/RantService.cfc +++ b/modules_app/api/modules_app/v3/models/RantService.cfc @@ -1,80 +1,123 @@ /** * I am the Rant Service v3 */ -component extends="v3.models.BaseService" singleton accessors="true" { +component + extends="v3.models.BaseService" + singleton + accessors="true" +{ /** * Constructor */ - RantService function init() { + RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", + entityName = "rant", + tableName = "rants", parameterName = "rantID", - moduleName = "v3" + moduleName = "v3" ) return this; } - function list() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ); + array function list(){ + return queryExecute( + "select * from rants ORDER BY createdDate DESC", + {} + ) + .reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } - function get( required numeric rantID ) { + struct function get( required numeric rantID ){ return queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } - ); + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + } + ).reduce( ( result, row ) => { + return row; + }, {} ); } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required body, required numeric userID ) { + function create( required body, required numeric userID ){ var now = now(); queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#body#", type: "cf_sql_longvarchar" }, - userID: { value: "#userID#", type: "cf_sql_numeric" }, - createdDate: { value: "#now#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + userID : { + value : "#userID#", + cfsqltype : "cf_sql_numeric" + }, + createdDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } - function update( required body, ) { + function update( required body, required rantId ){ var now = now(); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#rantID#", type: "cf_sql_integer" }, - body: { value: "#body#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#now#", type: "cf_sql_timestamp" } + rantID : { + value : "#rantID#", + cfsqltype : "cf_sql_integer" + }, + body : { + value : "#body#", + cfsqltype : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#now#", + cfsqltype : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } diff --git a/modules_app/api/modules_app/v3/models/UserService.cfc b/modules_app/api/modules_app/v3/models/UserService.cfc index cbf5825..64dca06 100644 --- a/modules_app/api/modules_app/v3/models/UserService.cfc +++ b/modules_app/api/modules_app/v3/models/UserService.cfc @@ -1,27 +1,36 @@ /** * I am the User Service v3 */ -component extends="v3.models.BaseService" singleton accessors="true" { +component + extends="v3.models.BaseService" + singleton + accessors="true" +{ /** * Constructor */ - UserService function init() { + UserService function init(){ super.init( - entityName = "user", - tableName = "users", + entityName = "user", + tableName = "users", parameterName = "userID", - moduleName = "v3" + moduleName = "v3" ) return this; } - function get( required numeric userID ) { + function get( required numeric userID ){ return queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); } diff --git a/modules_app/api/modules_app/v4/ModuleConfig.cfc b/modules_app/api/modules_app/v4/ModuleConfig.cfc index 00a22a9..751c13e 100644 --- a/modules_app/api/modules_app/v4/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v4/ModuleConfig.cfc @@ -1,17 +1,17 @@ /** Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. +this.title = "Title of the module"; +this.author = "Author of the module"; +this.webURL = "Web URL for docs purposes"; +this.description = "Module description"; +this.version = "Module Version"; +this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework +this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; +this.cfmapping = "The CF mapping to create"; this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" +this.dependencies = "The array of dependencies for this module" structures to create for configuration - parentSettings : struct (will append and override parent) @@ -43,29 +43,29 @@ Optional Methods component { // Module Properties - this.title = "v4"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; + this.title = "v4"; + this.author = ""; + this.webURL = ""; + this.description = ""; + this.version = "1.0.0"; // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; + this.viewParentLookup = true; // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa this.layoutParentLookup = true; // Module Entry Point - this.entryPoint = "v4"; + this.entryPoint = "v4"; // Inherit entry point from parent, so this will be /api/v1 - this.inheritEntryPoint = true; + this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v4"; + this.modelNamespace = "v4"; // CF Mapping - this.cfmapping = "v4"; + this.cfmapping = "v4"; // Auto-map models - this.autoMapModels = true; + this.autoMapModels = true; // Module Dependencies - this.dependencies = []; + this.dependencies = []; - function configure() { + function configure(){ // parent settings parentSettings = {}; @@ -73,12 +73,12 @@ component { settings = {}; // Layout Settings - layoutSettings = { defaultLayout: "" }; + layoutSettings = { defaultLayout : "" }; // SES Routes: config/Router.cfc // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; + interceptorSettings = { customInterceptionPoints : "" }; // Custom Declared Interceptors interceptors = []; @@ -90,13 +90,13 @@ component { /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v4/config/Router.cfc b/modules_app/api/modules_app/v4/config/Router.cfc index c5fcf6b..da45da4 100644 --- a/modules_app/api/modules_app/v4/config/Router.cfc +++ b/modules_app/api/modules_app/v4/config/Router.cfc @@ -1,7 +1,11 @@ component { - function configure() { - resources( resource = "rants", parameterName = "rantID", except = [ "new", "edit" ] ); + function configure(){ + resources( + resource = "rants", + parameterName = "rantID", + except = [ "new", "edit" ] + ); route( "/", "echo.index" ); route( "/:handler/:action" ).end(); diff --git a/modules_app/api/modules_app/v4/handlers/Echo.cfc b/modules_app/api/modules_app/v4/handlers/Echo.cfc index fa5d0a1..6d61bed 100644 --- a/modules_app/api/modules_app/v4/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v4/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,7 +17,7 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( "Welcome to my ColdBox RESTFul Service v4" ); } diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 30c76c6..5ed113d 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -11,7 +11,7 @@ component extends="coldbox.system.RestHandler" { /** * Returns a list of Rants */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( rantService.listArray() ); // prc.response.setData( // rantService.list().map( function( rant ) { @@ -24,10 +24,10 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant * */ - function show( event, rc, prc ) { + function show( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) } @@ -36,10 +36,10 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant * */ - function delete( event, rc, prc ) { + function delete( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); rantService.existsOrFail( rc.rantID ) var result = rantService.delete( rc.rantID ); @@ -50,10 +50,13 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant * */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { userID: { required: true, type: "numeric" }, body: { required: true } } + target = rc, + constraints = { + userID : { required : true, type : "numeric" }, + body : { required : true } + } ); userService.existsOrFail( rc.userID ); var rant = rantService.new(); @@ -61,12 +64,15 @@ component extends="coldbox.system.RestHandler" { rant.setUserID( rc.userID ); // var rant = populateModel( rantService.new() ); validate( - target = rant, - constraints = { body: { required: true }, userID: { required: true, type: "numeric" } } + target = rant, + constraints = { + body : { required : true }, + userID : { required : true, type : "numeric" } + } ); var result = rantService.create( rant ); - prc.response.setData( { "rantID": result.getID() } ); + prc.response.setData( { "rantID" : result.getID() } ); prc.response.addMessage( "Rant created" ); } @@ -74,13 +80,13 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant * */ - function update( event, rc, prc ) { + function update( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, + target = rc, constraints = { - rantID: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + rantID : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ); @@ -95,11 +101,11 @@ component extends="coldbox.system.RestHandler" { var rant = populateModel( model = rantService.new() ); rant.setID( rc.rantID ) validate( - target = rant, + target = rant, constraints = { - id: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + id : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ); var result = rantService.update( rant ); diff --git a/modules_app/api/modules_app/v4/models/BaseService.cfc b/modules_app/api/modules_app/v4/models/BaseService.cfc index 3231685..ae8ee42 100644 --- a/modules_app/api/modules_app/v4/models/BaseService.cfc +++ b/modules_app/api/modules_app/v4/models/BaseService.cfc @@ -13,11 +13,11 @@ component accessors="true" { function init( entityName, tableName, - primaryKey = "id", + primaryKey = "id", // parameterName="", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); @@ -39,13 +39,18 @@ component accessors="true" { * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists() { + boolean function exists(){ return booleanFormat( queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { id: { value: arguments[ 1 ], type: "cf_sql_numeric" } }, - { returntype: "array" } + { + id : { + value : arguments[ 1 ], + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } @@ -56,7 +61,7 @@ component accessors="true" { * @return Returns true if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function existsOrFail() { + function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } else { @@ -70,7 +75,7 @@ component accessors="true" { * @return Returns the Entity if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function getOrFail() { + function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); diff --git a/modules_app/api/modules_app/v4/models/Rant.cfc b/modules_app/api/modules_app/v4/models/Rant.cfc index b36bd7d..aa71e5a 100644 --- a/modules_app/api/modules_app/v4/models/Rant.cfc +++ b/modules_app/api/modules_app/v4/models/Rant.cfc @@ -7,41 +7,41 @@ component accessors="true" { property name="userService" inject="UserService@v4"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="userID" type="string"; /** * Constructor */ - Rant function init() { + Rant function init(){ return this; } /** * getUser */ - function getUser() { + function getUser(){ return userService.get( getUserID() ); } /** * isLoaded */ - boolean function isLoaded() { + boolean function isLoaded(){ return ( !isNull( variables.id ) && len( variables.id ) ); } - function getMemento() { + function getMemento(){ return { - "id": getID(), - "body": getBody(), - "createdDate": dateFormat( getCreatedDate(), "long" ), - "modifiedDate": dateFormat( getModifiedDate(), "long" ), - "userId": getUserID() + "id" : getID(), + "body" : getBody(), + "createdDate" : dateFormat( getCreatedDate(), "long" ), + "modifiedDate" : dateFormat( getModifiedDate(), "long" ), + "userId" : getUserID() }; } diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index 31d7350..1bc4d17 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -1,7 +1,11 @@ /** * I am the Rant Service v4 */ -component extends="v4.models.BaseService" singleton accessors="true" { +component + extends="v4.models.BaseService" + singleton + accessors="true" +{ // To populate objects from data property name="populator" inject="wirebox:populator"; @@ -9,37 +13,46 @@ component extends="v4.models.BaseService" singleton accessors="true" { /** * Constructor */ - RantService function init() { + RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", + entityName = "rant", + tableName = "rants", parameterName = "rantID", - moduleName = "v4" + moduleName = "v4" ) return this; } - Rant function new() provider="Rant@v4" { + Rant function new() provider="Rant@v4"{ } - function list() { + function list(){ return this .listArray() - .map( function( rant ) { + .map( function( rant ){ return populator.populateFromStruct( new (), rant ); } ); } - function listArray() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ) + function listArray(){ + return queryExecute( + "select * from rants ORDER BY createdDate DESC", + {}, + { returntype : "array" } + ) } - Rant function get( required numeric rantID ) { + Rant function get( required numeric rantID ){ var q = queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); @@ -48,17 +61,22 @@ component extends="v4.models.BaseService" singleton accessors="true" { } } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required Rant rant ) { + function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); arguments.rant.setModifiedDate( now ); @@ -66,39 +84,60 @@ component extends="v4.models.BaseService" singleton accessors="true" { queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - userID: { value: "#arguments.rant.getuserID()#", type: "cf_sql_numeric" }, - createdDate: { value: "#arguments.rant.getCreatedDate()#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + userID : { + value : "#arguments.rant.getuserID()#", + type : "cf_sql_numeric" + }, + createdDate : { + value : "#arguments.rant.getCreatedDate()#", + type : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } - function update( required Rant rant ) { + function update( required Rant rant ){ var now = now(); arguments.rant.setModifiedDate( now ); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#arguments.rant.getID()#", type: "cf_sql_integer" }, - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + rantID : { + value : "#arguments.rant.getID()#", + type : "cf_sql_integer" + }, + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } diff --git a/modules_app/api/modules_app/v4/models/UserService.cfc b/modules_app/api/modules_app/v4/models/UserService.cfc index ab35610..dc2de8d 100644 --- a/modules_app/api/modules_app/v4/models/UserService.cfc +++ b/modules_app/api/modules_app/v4/models/UserService.cfc @@ -1,27 +1,36 @@ /** * I am the User Service V4 */ -component extends="v4.models.BaseService" singleton accessors="true" { +component + extends="v4.models.BaseService" + singleton + accessors="true" +{ /** * Constructor */ - UserService function init() { + UserService function init(){ super.init( - entityName = "user", - tableName = "users", + entityName = "user", + tableName = "users", parameterName = "userID", - moduleName = "v4" + moduleName = "v4" ) return this; } - User function get( required numeric userID ) { + User function get( required numeric userID ){ var q = queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); diff --git a/modules_app/api/modules_app/v5/ModuleConfig.cfc b/modules_app/api/modules_app/v5/ModuleConfig.cfc index 816e9d3..d63c69a 100644 --- a/modules_app/api/modules_app/v5/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v5/ModuleConfig.cfc @@ -1,17 +1,17 @@ /** Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. +this.title = "Title of the module"; +this.author = "Author of the module"; +this.webURL = "Web URL for docs purposes"; +this.description = "Module description"; +this.version = "Module Version"; +this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework +this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; +this.cfmapping = "The CF mapping to create"; this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" +this.dependencies = "The array of dependencies for this module" structures to create for configuration - parentSettings : struct (will append and override parent) @@ -43,29 +43,29 @@ Optional Methods component { // Module Properties - this.title = "v5"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; + this.title = "v5"; + this.author = ""; + this.webURL = ""; + this.description = ""; + this.version = "1.0.0"; // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; + this.viewParentLookup = true; // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa this.layoutParentLookup = true; // Module Entry Point - this.entryPoint = "v5"; + this.entryPoint = "v5"; // Inherit entry point from parent, so this will be /api/v1 - this.inheritEntryPoint = true; + this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v5"; + this.modelNamespace = "v5"; // CF Mapping - this.cfmapping = "v5"; + this.cfmapping = "v5"; // Auto-map models - this.autoMapModels = true; + this.autoMapModels = true; // Module Dependencies - this.dependencies = []; + this.dependencies = []; - function configure() { + function configure(){ // parent settings parentSettings = {}; @@ -73,12 +73,12 @@ component { settings = {}; // Layout Settings - layoutSettings = { defaultLayout: "" }; + layoutSettings = { defaultLayout : "" }; // SES Routes: config/Router.cfc // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; + interceptorSettings = { customInterceptionPoints : "" }; // Custom Declared Interceptors interceptors = []; @@ -90,13 +90,13 @@ component { /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v5/config/Router.cfc b/modules_app/api/modules_app/v5/config/Router.cfc index c5fcf6b..da45da4 100644 --- a/modules_app/api/modules_app/v5/config/Router.cfc +++ b/modules_app/api/modules_app/v5/config/Router.cfc @@ -1,7 +1,11 @@ component { - function configure() { - resources( resource = "rants", parameterName = "rantID", except = [ "new", "edit" ] ); + function configure(){ + resources( + resource = "rants", + parameterName = "rantID", + except = [ "new", "edit" ] + ); route( "/", "echo.index" ); route( "/:handler/:action" ).end(); diff --git a/modules_app/api/modules_app/v5/handlers/Echo.cfc b/modules_app/api/modules_app/v5/handlers/Echo.cfc index 0259388..4b04642 100644 --- a/modules_app/api/modules_app/v5/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v5/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,7 +17,7 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( "Welcome to my ColdBox RESTFul Service v5" ); } diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index 8aba29a..e78f307 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -11,7 +11,7 @@ component extends="coldbox.system.RestHandler" { /** * Returns a list of Rants */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( rantService.listArray() ); } @@ -19,10 +19,10 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant * */ - function show( event, rc, prc ) { + function show( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) } @@ -31,10 +31,10 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant * */ - function delete( event, rc, prc ) { + function delete( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); rantService.getOrFail( rc.rantID ).delete(); prc.response.addMessage( "Rant deleted" ); @@ -44,17 +44,23 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant * */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { userID: { required: true, type: "numeric" }, body: { required: true } } + target = rc, + constraints = { + userID : { required : true, type : "numeric" }, + body : { required : true } + } ); userService.existsOrFail( rc.userID ); var result = rantService .new( validationResults ) - .validateOrFail( { body: { required: true }, userID: { required: true, type: "numeric" } } ) + .validateOrFail( { + body : { required : true }, + userID : { required : true, type : "numeric" } + } ) .save(); - prc.response.setData( { "rantID": result.getID() } ); + prc.response.setData( { "rantID" : result.getID() } ); prc.response.addMessage( "Rant created" ); } @@ -62,13 +68,13 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant * */ - function update( event, rc, prc ) { + function update( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, + target = rc, constraints = { - rantID: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + rantID : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ); userService.existsOrFail( rc.userID ); @@ -78,9 +84,9 @@ component extends="coldbox.system.RestHandler" { .setID( rc.rantID ) .validateOrFail( constraints = { - id: { required: true, type: "numeric" }, - body: { required: true }, - userID: { required: true, type: "numeric" } + id : { required : true, type : "numeric" }, + body : { required : true }, + userID : { required : true, type : "numeric" } } ) .save(); diff --git a/modules_app/api/modules_app/v5/models/BaseEntity.cfc b/modules_app/api/modules_app/v5/models/BaseEntity.cfc index 2eee216..070cb32 100644 --- a/modules_app/api/modules_app/v5/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v5/models/BaseEntity.cfc @@ -19,11 +19,11 @@ component accessors="true" { * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards */ function init( - pk = "id", - entityName = "", + pk = "id", + entityName = "", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setPk( arguments.pk ); if ( len( entityName ) ) { setEntityName( arguments.entityName ); @@ -42,7 +42,7 @@ component accessors="true" { /** * Verify if entity is loaded or not */ - boolean function isLoaded() { + boolean function isLoaded(){ return ( isNull( variables[ getPk() ] ) OR !len( variables[ getPk() ] ) ? false : true ); } @@ -67,20 +67,20 @@ component accessors="true" { .getRequestService() .getContext() .getCollection(), - scope = "", - boolean trustedSetter = false, - include = "", - exclude = "", - boolean ignoreEmpty = false, - nullEmptyInclude = "", - nullEmptyExclude = "", + scope = "", + boolean trustedSetter = false, + include = "", + exclude = "", + boolean ignoreEmpty = false, + nullEmptyInclude = "", + nullEmptyExclude = "", boolean composeRelationships = false, string jsonstring, string xml, query qry - ) { + ){ arguments[ "model" ] = this; - arguments.target = this; + arguments.target = this; // json? if ( structKeyExists( arguments, "jsonstring" ) ) { @@ -113,33 +113,33 @@ component accessors="true" { * @throws ValidationException error */ public struct function validateOrFail( - any constraints = {}, - string fields = "*", - string locale = "", + any constraints = {}, + string fields = "*", + string locale = "", string excludeFields = "", string includeFields = "" - ) { + ){ var result = wirebox .getInstance( "ValidationManager@cbvalidation" ) .validate( - target = this, - fields = arguments.fields, - constraints = arguments.constraints, - locale = arguments.locale, + target = this, + fields = arguments.fields, + constraints = arguments.constraints, + locale = arguments.locale, excludeFields = arguments.excludeFields, includeFields = arguments.includeFields ); if ( result.hasErrors() ) { throw( - type = "ValidationException", - message = "The Model #getEntityName()# failed to pass validation", + type = "ValidationException", + message = "The Model #getEntityName()# failed to pass validation", extendedInfo = serializeJSON( result.getAllErrors() ) ); } return this; } - function save() { + function save(){ if ( isLoaded() ) { return wirebox.getInstance( "#getServiceName()#" ).update( this ); } else { @@ -147,21 +147,21 @@ component accessors="true" { } } - function delete() { + function delete(){ return wirebox.getInstance( "#getServiceName()#" ).delete( this.getID() ); } this.memento = { // An array of the properties/relationships to include by default - defaultIncludes: [ "*" ], + defaultIncludes : [ "*" ], // An array of properties/relationships to exclude by default - defaultExcludes: [], + defaultExcludes : [], // An array of properties/relationships to NEVER include - neverInclude: [], + neverInclude : [], // A struct of defaults for properties/relationships if they are null - defaults: {}, + defaults : {}, // A struct of mapping functions for properties/relationships that can transform them - mappers: {} + mappers : {} } } diff --git a/modules_app/api/modules_app/v5/models/BaseService.cfc b/modules_app/api/modules_app/v5/models/BaseService.cfc index e812a4c..2b66251 100644 --- a/modules_app/api/modules_app/v5/models/BaseService.cfc +++ b/modules_app/api/modules_app/v5/models/BaseService.cfc @@ -13,11 +13,11 @@ component accessors="true" { function init( entityName, tableName, - primaryKey = "id", + primaryKey = "id", // parameterName="", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); @@ -42,7 +42,7 @@ component accessors="true" { * * @data Data to populate the new Entity with */ - function new( struct data = {} ) { + function new( struct data = {} ){ // if( data.isEmpty() ){ // } else { @@ -59,13 +59,18 @@ component accessors="true" { * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists() { + boolean function exists(){ return booleanFormat( queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { id: { value: arguments[ 1 ], type: "cf_sql_numeric" } }, - { returntype: "array" } + { + id : { + value : arguments[ 1 ], + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } @@ -76,7 +81,7 @@ component accessors="true" { * @return Returns true if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function existsOrFail() { + function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } else { @@ -90,7 +95,7 @@ component accessors="true" { * @return Returns the Entity if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function getOrFail() { + function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); diff --git a/modules_app/api/modules_app/v5/models/Rant.cfc b/modules_app/api/modules_app/v5/models/Rant.cfc index cbaddef..2c46252 100644 --- a/modules_app/api/modules_app/v5/models/Rant.cfc +++ b/modules_app/api/modules_app/v5/models/Rant.cfc @@ -7,17 +7,17 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="userService" inject="UserService@v5"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="userID" type="string"; /** * Constructor */ - Rant function init() { + Rant function init(){ super.init( entityName = "rant", moduleName = "v5" ); return this; } @@ -25,7 +25,7 @@ component extends="v5.models.BaseEntity" accessors="true" { /** * getUser */ - function getUser() { + function getUser(){ return userService.get( getUserID() ); } diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index 434e180..b50b087 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -1,43 +1,56 @@ /** * I am the Rant Service v5 */ -component extends="v5.models.BaseService" singleton accessors="true" { +component + extends="v5.models.BaseService" + singleton + accessors="true" +{ // DI Injection - property name="wirebox" inject="wirebox"; + property name="wirebox" inject="wirebox"; property name="populator" inject="wirebox:populator"; /** * Constructor */ - RantService function init() { + RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", + entityName = "rant", + tableName = "rants", parameterName = "rantID", - moduleName = "v5" + moduleName = "v5" ) return this; } - function list() { + function list(){ return this .listArray() - .map( function( rant ) { + .map( function( rant ){ return populator.populateFromStruct( new (), rant ); } ); } - function listArray() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ) + function listArray(){ + return queryExecute( + "select * from rants ORDER BY createdDate DESC", + {}, + { returntype : "array" } + ) } - Rant function get( required numeric rantID ) { + Rant function get( required numeric rantID ){ var q = queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); @@ -46,17 +59,22 @@ component extends="v5.models.BaseService" singleton accessors="true" { } } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required Rant rant ) { + function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); arguments.rant.setModifiedDate( now ); @@ -64,39 +82,60 @@ component extends="v5.models.BaseService" singleton accessors="true" { queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - userID: { value: "#arguments.rant.getuserID()#", type: "cf_sql_numeric" }, - createdDate: { value: "#arguments.rant.getCreatedDate()#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + userID : { + value : "#arguments.rant.getuserID()#", + type : "cf_sql_numeric" + }, + createdDate : { + value : "#arguments.rant.getCreatedDate()#", + type : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } - function update( required Rant rant ) { + function update( required Rant rant ){ var now = now(); arguments.rant.setModifiedDate( now ); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#arguments.rant.getID()#", type: "cf_sql_integer" }, - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + rantID : { + value : "#arguments.rant.getID()#", + type : "cf_sql_integer" + }, + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } diff --git a/modules_app/api/modules_app/v5/models/UserService.cfc b/modules_app/api/modules_app/v5/models/UserService.cfc index f65916c..ca72884 100644 --- a/modules_app/api/modules_app/v5/models/UserService.cfc +++ b/modules_app/api/modules_app/v5/models/UserService.cfc @@ -1,27 +1,36 @@ /** * I am the User Service v5 */ -component extends="v5.models.BaseService" singleton accessors="true" { +component + extends="v5.models.BaseService" + singleton + accessors="true" +{ /** * Constructor */ - UserService function init() { + UserService function init(){ super.init( - entityName = "user", - tableName = "users", + entityName = "user", + tableName = "users", parameterName = "userID", - moduleName = "v5" + moduleName = "v5" ) return this; } - User function get( required numeric userID ) { + User function get( required numeric userID ){ var q = queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); diff --git a/modules_app/api/modules_app/v6/ModuleConfig.cfc b/modules_app/api/modules_app/v6/ModuleConfig.cfc index b72990b..fd36862 100644 --- a/modules_app/api/modules_app/v6/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v6/ModuleConfig.cfc @@ -1,17 +1,17 @@ /** Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. +this.title = "Title of the module"; +this.author = "Author of the module"; +this.webURL = "Web URL for docs purposes"; +this.description = "Module description"; +this.version = "Module Version"; +this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework +this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; +this.cfmapping = "The CF mapping to create"; this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" +this.dependencies = "The array of dependencies for this module" structures to create for configuration - parentSettings : struct (will append and override parent) @@ -43,29 +43,29 @@ Optional Methods component { // Module Properties - this.title = "v6"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; + this.title = "v6"; + this.author = ""; + this.webURL = ""; + this.description = ""; + this.version = "1.0.0"; // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; + this.viewParentLookup = true; // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa this.layoutParentLookup = true; // Module Entry Point - this.entryPoint = "v6"; + this.entryPoint = "v6"; // Inherit entry point from parent, so this will be /api/v1 - this.inheritEntryPoint = true; + this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v6"; + this.modelNamespace = "v6"; // CF Mapping - this.cfmapping = "v6"; + this.cfmapping = "v6"; // Auto-map models - this.autoMapModels = true; + this.autoMapModels = true; // Module Dependencies - this.dependencies = []; + this.dependencies = []; - function configure() { + function configure(){ // parent settings parentSettings = {}; @@ -73,12 +73,12 @@ component { settings = {}; // Layout Settings - layoutSettings = { defaultLayout: "" }; + layoutSettings = { defaultLayout : "" }; // SES Routes: config/Router.cfc // Custom Declared Points - interceptorSettings = { customInterceptionPoints: "" }; + interceptorSettings = { customInterceptionPoints : "" }; // Custom Declared Interceptors interceptors = []; @@ -90,13 +90,13 @@ component { /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/modules_app/v6/config/Router.cfc b/modules_app/api/modules_app/v6/config/Router.cfc index c5fcf6b..da45da4 100644 --- a/modules_app/api/modules_app/v6/config/Router.cfc +++ b/modules_app/api/modules_app/v6/config/Router.cfc @@ -1,7 +1,11 @@ component { - function configure() { - resources( resource = "rants", parameterName = "rantID", except = [ "new", "edit" ] ); + function configure(){ + resources( + resource = "rants", + parameterName = "rantID", + except = [ "new", "edit" ] + ); route( "/", "echo.index" ); route( "/:handler/:action" ).end(); diff --git a/modules_app/api/modules_app/v6/handlers/Echo.cfc b/modules_app/api/modules_app/v6/handlers/Echo.cfc index 1296b45..897615e 100644 --- a/modules_app/api/modules_app/v6/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v6/handlers/Echo.cfc @@ -4,11 +4,11 @@ component extends="coldbox.system.RestHandler" { // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; + this.prehandler_only = ""; + this.prehandler_except = ""; + this.posthandler_only = ""; + this.posthandler_except = ""; + this.aroundHandler_only = ""; this.aroundHandler_except = ""; // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} @@ -17,7 +17,7 @@ component extends="coldbox.system.RestHandler" { /** * Index */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( "Welcome to my ColdBox RESTFul Service v6" ); } diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index c1f911a..0478fd8 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -15,7 +15,7 @@ component displayName="Rants" extends="coldbox.system.RestHandler" { * * @response-200 /resources/apidocs/api-v6/Rants/index/responses.json##200 */ - any function index( event, rc, prc ) { + any function index( event, rc, prc ){ prc.response.setData( rantService.listArray() ); } @@ -28,10 +28,10 @@ component displayName="Rants" extends="coldbox.system.RestHandler" { * @response-200 /resources/apidocs/api-v6/Rants/show/responses.json##200 * @response-404 /resources/apidocs/_responses/rant.404.json */ - function show( event, rc, prc ) { + function show( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) } @@ -45,10 +45,10 @@ component displayName="Rants" extends="coldbox.system.RestHandler" { * @response-200 /resources/apidocs/api-v6/Rants/delete/responses.json##200 * @response-404 /resources/apidocs/_responses/rant.404.json */ - function delete( event, rc, prc ) { + function delete( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = { rantID: { required: true, type: "numeric" } } + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } ); rantService.getOrFail( rc.rantID ).delete(); prc.response.addMessage( "Rant deleted" ); @@ -63,14 +63,14 @@ component displayName="Rants" extends="coldbox.system.RestHandler" { * @response-200 /resources/apidocs/api-v6/Rants/create/responses.json##200 * @response-412 /resources/apidocs/api-v6/Rants/create/responses.json##412 */ - function create( event, rc, prc ) { + function create( event, rc, prc ){ var validationResults = validateOrFail( target = rc, constraints = rantService.getConstraints() ); userService.existsOrFail( rc.userID ); var result = rantService .new( validationResults ) .validateOrFail( rantService.getConstraints() ) .save(); - prc.response.setData( { "rantID": result.getID() } ); + prc.response.setData( { "rantID" : result.getID() } ); prc.response.addMessage( "Rant created" ); } @@ -83,17 +83,19 @@ component displayName="Rants" extends="coldbox.system.RestHandler" { * @response-200 /resources/apidocs/api-v6/Rants/update/responses.json##200 * @response-412 /resources/apidocs/api-v6/Rants/update/responses.json##412 */ - function update( event, rc, prc ) { + function update( event, rc, prc ){ var validationResults = validateOrFail( - target = rc, - constraints = rantService.addConstraints( { rantID: { required: true, type: "numeric" } } ) + target = rc, + constraints = rantService.addConstraints( { rantID : { required : true, type : "numeric" } } ) ); userService.existsOrFail( rc.userID ); rantService .getOrFail( rc.rantID ) .populate( validationResults ) .setID( rc.rantID ) - .validateOrFail( constraints = rantService.addConstraints( { ID: { required: true, type: "numeric" } } ) ) + .validateOrFail( + constraints = rantService.addConstraints( { ID : { required : true, type : "numeric" } } ) + ) .save(); prc.response.addMessage( "Rant Updated" ); } diff --git a/modules_app/api/modules_app/v6/models/BaseEntity.cfc b/modules_app/api/modules_app/v6/models/BaseEntity.cfc index 3828125..1a19b66 100644 --- a/modules_app/api/modules_app/v6/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v6/models/BaseEntity.cfc @@ -19,11 +19,11 @@ component accessors="true" { * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards */ function init( - pk = "id", - entityName = "", + pk = "id", + entityName = "", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setPk( arguments.pk ); if ( len( entityName ) ) { setEntityName( arguments.entityName ); @@ -42,7 +42,7 @@ component accessors="true" { /** * Verify if entity is loaded or not */ - boolean function isLoaded() { + boolean function isLoaded(){ return ( isNull( variables[ getPk() ] ) OR !len( variables[ getPk() ] ) ? false : true ); } @@ -67,20 +67,20 @@ component accessors="true" { .getRequestService() .getContext() .getCollection(), - scope = "", - boolean trustedSetter = false, - include = "", - exclude = "", - boolean ignoreEmpty = false, - nullEmptyInclude = "", - nullEmptyExclude = "", + scope = "", + boolean trustedSetter = false, + include = "", + exclude = "", + boolean ignoreEmpty = false, + nullEmptyInclude = "", + nullEmptyExclude = "", boolean composeRelationships = false, string jsonstring, string xml, query qry - ) { + ){ arguments[ "model" ] = this; - arguments.target = this; + arguments.target = this; // json? if ( structKeyExists( arguments, "jsonstring" ) ) { @@ -113,33 +113,33 @@ component accessors="true" { * @throws ValidationException error */ public struct function validateOrFail( - any constraints = {}, - string fields = "*", - string locale = "", + any constraints = {}, + string fields = "*", + string locale = "", string excludeFields = "", string includeFields = "" - ) { + ){ var result = wirebox .getInstance( "ValidationManager@cbvalidation" ) .validate( - target = this, - fields = arguments.fields, - constraints = arguments.constraints, - locale = arguments.locale, + target = this, + fields = arguments.fields, + constraints = arguments.constraints, + locale = arguments.locale, excludeFields = arguments.excludeFields, includeFields = arguments.includeFields ); if ( result.hasErrors() ) { throw( - type = "ValidationException", - message = "The Model #getEntityName()# failed to pass validation", + type = "ValidationException", + message = "The Model #getEntityName()# failed to pass validation", extendedInfo = serializeJSON( result.getAllErrors() ) ); } return this; } - function save() { + function save(){ if ( isLoaded() ) { return wirebox.getInstance( "#getServiceName()#" ).update( this ); } else { @@ -147,25 +147,25 @@ component accessors="true" { } } - function delete() { + function delete(){ return wirebox.getInstance( "#getServiceName()#" ).delete( this.getID() ); } this.memento = { // An array of the properties/relationships to include by default - defaultIncludes: [ "*" ], + defaultIncludes : [ "*" ], // An array of properties/relationships to exclude by default - defaultExcludes: [], + defaultExcludes : [], // An array of properties/relationships to NEVER include - neverInclude: [ + neverInclude : [ "entityName", "pk", "serviceName", "moduleName" ], // A struct of defaults for properties/relationships if they are null - defaults: {}, + defaults : {}, // A struct of mapping functions for properties/relationships that can transform them - mappers: {} + mappers : {} } } diff --git a/modules_app/api/modules_app/v6/models/BaseService.cfc b/modules_app/api/modules_app/v6/models/BaseService.cfc index 6855340..33ab744 100644 --- a/modules_app/api/modules_app/v6/models/BaseService.cfc +++ b/modules_app/api/modules_app/v6/models/BaseService.cfc @@ -13,11 +13,11 @@ component accessors="true" { function init( entityName, tableName, - primaryKey = "id", + primaryKey = "id", // parameterName="", serviceName = "", - moduleName = "" - ) { + moduleName = "" + ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); @@ -42,7 +42,7 @@ component accessors="true" { * * @data Data to populate the new Entity with */ - function new( struct data = {} ) { + function new( struct data = {} ){ // if( data.isEmpty() ){ // } else { @@ -59,13 +59,18 @@ component accessors="true" { * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists() { + boolean function exists(){ return booleanFormat( queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { id: { value: arguments[ 1 ], type: "cf_sql_numeric" } }, - { returntype: "array" } + { + id : { + value : arguments[ 1 ], + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ).len() ) } @@ -76,7 +81,7 @@ component accessors="true" { * @return Returns true if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function existsOrFail() { + function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } else { @@ -90,7 +95,7 @@ component accessors="true" { * @return Returns the Entity if there is a row with the matching Primary Key * @throws EntityNotFound if the entity is not found */ - function getOrFail() { + function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); @@ -105,7 +110,7 @@ component accessors="true" { * * @return a CBValidation compliant struct of Entity Constraints */ - function getConstraints( string constraintsKeyName = "constraints" ) { + function getConstraints( string constraintsKeyName = "constraints" ){ return new ( {} )[ arguments.constraintsKeyName ]; } @@ -118,7 +123,7 @@ component accessors="true" { * * @return a CBValidation compliant struct of Entity Constraints */ - function addConstraints( newConstraints = {}, constraintsKeyName = "constraints" ) { + function addConstraints( newConstraints = {}, constraintsKeyName = "constraints" ){ var constraints = getConstraints( arguments.constraintsKeyName ); constraints.append( arguments.newConstraints ); return constraints; diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index 4f91e62..3efb2ce 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -7,27 +7,30 @@ component extends="v6.models.BaseEntity" accessors="true" { property name="userService" inject="UserService@v6"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="userID" type="string"; /** * Constructor */ - Rant function init() { + Rant function init(){ super.init( entityName = "rant", moduleName = "v6" ); return this; } - this.constraints = { userID: { required: true, type: "numeric" }, body: { required: true } }; + this.constraints = { + userID : { required : true, type : "numeric" }, + body : { required : true } + }; /** * getUser */ - function getUser() { + function getUser(){ return userService.get( getUserID() ); } diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index 3d320a9..b12b61b 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -1,43 +1,56 @@ /** * I am the Rant Service v6 */ -component extends="v6.models.BaseService" singleton accessors="true" { +component + extends="v6.models.BaseService" + singleton + accessors="true" +{ // DI Injection - property name="wirebox" inject="wirebox"; + property name="wirebox" inject="wirebox"; property name="populator" inject="wirebox:populator"; /** * Constructor */ - RantService function init() { + RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", + entityName = "rant", + tableName = "rants", parameterName = "rantID", - moduleName = "v6" + moduleName = "v6" ) return this; } - function list() { + function list(){ return this .listArray() - .map( function( rant ) { + .map( function( rant ){ return populator.populateFromStruct( new (), rant ); } ); } - function listArray() { - return queryExecute( "select * from rants ORDER BY createdDate DESC", {}, { returntype: "array" } ) + function listArray(){ + return queryExecute( + "select * from rants ORDER BY createdDate DESC", + {}, + { returntype : "array" } + ) } - Rant function get( required numeric rantID ) { + Rant function get( required numeric rantID ){ var q = queryExecute( "select * from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); @@ -46,17 +59,22 @@ component extends="v6.models.BaseService" singleton accessors="true" { } } - function delete( required numeric rantID ) { + function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { rantID: { value: "#rantID#", type: "cf_sql_numeric" } }, - { result: "local.result" } + { + rantID : { + value : "#rantID#", + type : "cf_sql_numeric" + } + }, + { result : "local.result" } ); return local.result; } - function create( required Rant rant ) { + function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); arguments.rant.setModifiedDate( now ); @@ -64,39 +82,60 @@ component extends="v6.models.BaseService" singleton accessors="true" { queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, + body = :body, + userID = :userID, + createdDate = :createdDate, modifiedDate = :modifiedDate ", { - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - userID: { value: "#arguments.rant.getuserID()#", type: "cf_sql_numeric" }, - createdDate: { value: "#arguments.rant.getCreatedDate()#", type: "cf_sql_timestamp" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + userID : { + value : "#arguments.rant.getuserID()#", + type : "cf_sql_numeric" + }, + createdDate : { + value : "#arguments.rant.getCreatedDate()#", + type : "cf_sql_timestamp" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } - function update( required Rant rant ) { + function update( required Rant rant ){ var now = now(); arguments.rant.setModifiedDate( now ); queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { - rantID: { value: "#arguments.rant.getID()#", type: "cf_sql_integer" }, - body: { value: "#arguments.rant.getBody()#", type: "cf_sql_longvarchar" }, - modifiedDate: { value: "#arguments.rant.getModifiedDate()#", type: "cf_sql_timestamp" } + rantID : { + value : "#arguments.rant.getID()#", + type : "cf_sql_integer" + }, + body : { + value : "#arguments.rant.getBody()#", + type : "cf_sql_longvarchar" + }, + modifiedDate : { + value : "#arguments.rant.getModifiedDate()#", + type : "cf_sql_timestamp" + } }, - { result: "local.result" } + { result : "local.result" } ); return local.result; } diff --git a/modules_app/api/modules_app/v6/models/UserService.cfc b/modules_app/api/modules_app/v6/models/UserService.cfc index a612a7d..8665ccd 100644 --- a/modules_app/api/modules_app/v6/models/UserService.cfc +++ b/modules_app/api/modules_app/v6/models/UserService.cfc @@ -1,27 +1,36 @@ /** * I am the User Service v6 */ -component extends="v6.models.BaseService" singleton accessors="true" { +component + extends="v6.models.BaseService" + singleton + accessors="true" +{ /** * Constructor */ - UserService function init() { + UserService function init(){ super.init( - entityName = "user", - tableName = "users", + entityName = "user", + tableName = "users", parameterName = "userID", - moduleName = "v6" + moduleName = "v6" ) return this; } - User function get( required numeric userID ) { + User function get( required numeric userID ){ var q = queryExecute( "select * from users where id = :userID", - { userID: { value: "#userID#", type: "cf_sql_numeric" } }, - { returntype: "array" } + { + userID : { + value : "#userID#", + type : "cf_sql_numeric" + } + }, + { returntype : "array" } ); if ( q.len() ) { return populator.populateFromStruct( new (), q[ 1 ] ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 9394ab4..61c1710 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -17,7 +17,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); // expect( returnedJSON ).toHaveKey( "error" ); // expect( returnedJSON ).toHaveKey( "errors" ); - expect( returnedJSON ).toHaveKeyWithCase( "ERROR" ); // expect( returnedJSON ).toHaveKeyWithCase( "errors" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -32,19 +31,16 @@ component extends="tests.resources.BaseTest" appMapping="/" { scenario( "Get an individual Rant", function() { given( "I make a get call to /api/v3/rants/:rantID", function() { when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "x" var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -59,7 +55,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); } ); } ); @@ -73,7 +69,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( event ).toHaveStatusCode( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); expect( returnedJSON.data.id ).toBe( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); @@ -97,74 +93,67 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v3/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v3/rants", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v3/rants", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v3/rants", { "userID": "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v3/rants", { "userID": "5", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); @@ -179,7 +168,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); } ); } ); @@ -230,98 +219,88 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v3/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v3/rants/#rantID#", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v3/rants/#rantID#", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "1"; var event = put( "/api/v3/rants/#rantID#", { "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "1"; var event = put( "/api/v3/rants/#rantID#", { "userID": "1", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = put( "/api/v3/rants/#rantID#", { "userID": "1", "body": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -336,7 +315,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); } ); } ); @@ -351,7 +330,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); } ); } ); @@ -410,19 +389,16 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -437,7 +413,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); } ); } ); From e8c297c58d0b5a6883f32ecd83b653a1a56c3a25 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 May 2020 10:36:17 -0500 Subject: [PATCH 16/75] v3 finalized --- .cfformat.json | 8 +-- .../api/modules_app/v2/models/RantService.cfc | 12 ++-- .../api/modules_app/v2/models/UserService.cfc | 8 +-- .../api/modules_app/v3/handlers/Rants.cfc | 34 +++++------ .../api/modules_app/v3/models/BaseService.cfc | 18 +++--- .../api/modules_app/v3/models/RantService.cfc | 60 +++++++++---------- .../api/modules_app/v3/models/UserService.cfc | 5 +- 7 files changed, 71 insertions(+), 74 deletions(-) diff --git a/.cfformat.json b/.cfformat.json index ff8178c..1c6ee6d 100644 --- a/.cfformat.json +++ b/.cfformat.json @@ -17,19 +17,19 @@ "function_call.multiline.leading_comma.padding": true, "function_call.casing.builtin": "cfdocs", "function_call.casing.userdefined": "camel", - "function_call.multiline.element_count": 3, + "function_call.multiline.element_count": 2, "function_call.multiline.leading_comma": false, "function_call.multiline.min_length": 40, "function_declaration.padding": true, "function_declaration.empty_padding": false, "function_declaration.multiline.leading_comma": false, "function_declaration.multiline.leading_comma.padding": true, - "function_declaration.multiline.element_count": 3, + "function_declaration.multiline.element_count": 2, "function_declaration.multiline.min_length": 40, "function_declaration.group_to_block_spacing": "compact", "function_anonymous.empty_padding": false, "function_anonymous.group_to_block_spacing": "compact", - "function_anonymous.multiline.element_count": 3, + "function_anonymous.multiline.element_count": 2, "function_anonymous.multiline.leading_comma": false, "function_anonymous.multiline.leading_comma.padding": true, "function_anonymous.multiline.min_length": 40, @@ -55,7 +55,7 @@ "struct.empty_padding": false, "struct.multiline.leading_comma": false, "struct.multiline.leading_comma.padding": true, - "struct.multiline.element_count": 2, + "struct.multiline.element_count": 1, "struct.multiline.min_length": 40, "tab_indent": true } \ No newline at end of file diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index ef55a82..388ae29 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -11,10 +11,11 @@ component singleton accessors="true" { } array function list(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ) + .reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } struct function get( required numeric rantID ){ @@ -118,8 +119,7 @@ component singleton accessors="true" { value : "#rantID#", cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } diff --git a/modules_app/api/modules_app/v2/models/UserService.cfc b/modules_app/api/modules_app/v2/models/UserService.cfc index c87ef02..6e89209 100644 --- a/modules_app/api/modules_app/v2/models/UserService.cfc +++ b/modules_app/api/modules_app/v2/models/UserService.cfc @@ -20,10 +20,7 @@ component singleton accessors="true" { type : "cf_sql_numeric" } } - ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); + ).reduce( ( result, row ) => row, {} ); } boolean function exists( required numeric userID ){ @@ -36,8 +33,7 @@ component singleton accessors="true" { value : "#userID#", type : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 68dea36..c3c3ed4 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -20,13 +20,13 @@ component extends="coldbox.system.RestHandler" { * */ function show( event, rc, prc ){ - var validationResults = validateOrFail( + validateOrFail( target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - prc.response.setData( - rantService.getOrFail( rc.rantID ) + constraints = { + rantID : { required : true, type : "numeric" } + } ); + prc.response.setData( rantService.getOrFail( rc.rantID ) ); } /** @@ -36,10 +36,12 @@ component extends="coldbox.system.RestHandler" { function delete( event, rc, prc ){ var validationResults = validateOrFail( target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + constraints = { + rantID : { required : true, type : "numeric" } + } ); rantService.existsOrFail( rc.rantID ) - var result = rantService.delete( rc.rantID ); + rantService.delete( rc.rantID ); prc.response.addMessage( "Rant deleted" ); } @@ -48,7 +50,7 @@ component extends="coldbox.system.RestHandler" { * */ function create( event, rc, prc ){ - var validationResults = validateOrFail( + validateOrFail( target = rc, constraints = { userID : { required : true, type : "numeric" }, @@ -57,11 +59,8 @@ component extends="coldbox.system.RestHandler" { ); userService.existsOrFail( rc.userID ); var result = rantService.create( body = rc.body, userID = rc.userID ); - if ( result.recordcount ) { - prc.response.setData( { "rantID" : result.generatedKey } ); - prc.response.addMessage( "Rant created" ); - return; - } + prc.response.setData( { "rantID" : result.generatedKey } ); + prc.response.addMessage( "Rant created" ); } /** @@ -69,7 +68,7 @@ component extends="coldbox.system.RestHandler" { * */ function update( event, rc, prc ){ - var validationResults = validateOrFail( + validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" }, @@ -81,14 +80,13 @@ component extends="coldbox.system.RestHandler" { rantService.existsOrFail( rc.rantID ); userService.existsOrFail( rc.userID ); - var result = rantService.update( + rantService.update( body = rc.body, userID = rc.userID, rantID = rc.rantID ); - if ( result.recordcount ) { - prc.response.addMessage( "Rant Updated" ); - } + + prc.response.addMessage( "Rant Updated" ); } } diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index 71273e9..c8ec834 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -46,11 +46,10 @@ component accessors="true" { where #getPrimaryKey()# = :id", { id : { - value : arguments[ 1 ], - cfsqltype : "cf_sql_numeric" + value : arguments[ 1 ], + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } @@ -64,9 +63,11 @@ component accessors="true" { function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; - } else { - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } + throw( + type = "EntityNotFound", + message = "#entityName# Not Found" + ); } /** @@ -78,7 +79,10 @@ component accessors="true" { function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( maybeEntity.isEmpty() ) { - throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); + throw( + type = "EntityNotFound", + message = "#getEntityName()# Not Found" + ); } return maybeEntity; } diff --git a/modules_app/api/modules_app/v3/models/RantService.cfc b/modules_app/api/modules_app/v3/models/RantService.cfc index 1f2832b..0bec065 100644 --- a/modules_app/api/modules_app/v3/models/RantService.cfc +++ b/modules_app/api/modules_app/v3/models/RantService.cfc @@ -24,8 +24,7 @@ component return queryExecute( "select * from rants ORDER BY createdDate DESC", {} - ) - .reduce( ( result, row ) => { + ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); @@ -37,13 +36,11 @@ component where id = :rantID", { rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" + value : "#rantID#", + cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => { - return row; - }, {} ); + ).reduce( ( result, row ) => row, {} ); } function delete( required numeric rantID ){ @@ -52,8 +49,8 @@ component where id = :rantID", { rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" + value : "#rantID#", + cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } @@ -61,32 +58,35 @@ component return local.result; } - function create( required body, required numeric userID ){ + function create( + required body, + required numeric userID + ){ var now = now(); queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, - modifiedDate = :modifiedDate + body = :body, + userID = :userID, + createdDate = :createdDate, + modifiedDate = :modifiedDate ", { body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" + value : "#body#", + cfsqltype : "cf_sql_longvarchar" }, userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" + value : "#userID#", + cfsqltype : "cf_sql_numeric" }, createdDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" + value : "#now#", + cfsqltype : "cf_sql_timestamp" }, modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" + value : "#now#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -99,22 +99,22 @@ component queryExecute( "update rants set - body = :body, + body = :body, modifiedDate = :modifiedDate - where id = :rantID + where id = :rantID ", { rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_integer" + value : "#rantID#", + cfsqltype : "cf_sql_integer" }, body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" + value : "#body#", + cfsqltype : "cf_sql_longvarchar" }, modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" + value : "#now#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } diff --git a/modules_app/api/modules_app/v3/models/UserService.cfc b/modules_app/api/modules_app/v3/models/UserService.cfc index 64dca06..09aac04 100644 --- a/modules_app/api/modules_app/v3/models/UserService.cfc +++ b/modules_app/api/modules_app/v3/models/UserService.cfc @@ -29,9 +29,8 @@ component value : "#userID#", type : "cf_sql_numeric" } - }, - { returntype : "array" } - ); + } + ).reduce( ( result, row ) => row, {} ); } } From 6970c461d30bd321917b35555cbb4fc447fcadf1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 May 2020 11:26:56 -0500 Subject: [PATCH 17/75] finalized v4 --- .../api/modules_app/v4/ModuleConfig.cfc | 84 ++--------------- .../api/modules_app/v4/handlers/Rants.cfc | 94 +++++++------------ .../api/modules_app/v4/models/BaseService.cfc | 26 +++-- .../api/modules_app/v4/models/Rant.cfc | 8 ++ .../api/modules_app/v4/models/RantService.cfc | 50 +++++----- .../api/modules_app/v4/models/User.cfc | 42 +++++++++ .../api/modules_app/v4/models/UserService.cfc | 18 ++-- tests/specs/integration/api-v1/EchoTests.cfc | 2 +- tests/specs/integration/api-v1/RantsTest.cfc | 2 +- tests/specs/integration/api-v2/RantsTest.cfc | 2 +- tests/specs/integration/api-v3/RantsTest.cfc | 2 +- tests/specs/integration/api-v4/RantsTest.cfc | 93 +++++++----------- tests/specs/integration/api-v5/RantsTest.cfc | 2 +- tests/specs/integration/api-v6/RantsTest.cfc | 2 +- 14 files changed, 181 insertions(+), 246 deletions(-) create mode 100644 modules_app/api/modules_app/v4/models/User.cfc diff --git a/modules_app/api/modules_app/v4/ModuleConfig.cfc b/modules_app/api/modules_app/v4/ModuleConfig.cfc index 751c13e..e0eb01d 100644 --- a/modules_app/api/modules_app/v4/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v4/ModuleConfig.cfc @@ -1,90 +1,22 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * Module Config + */ component { // Module Properties - this.title = "v4"; - this.author = ""; - this.webURL = ""; - this.description = ""; - this.version = "1.0.0"; - // If true, looks for views in the parent first, if not found, then in the module. Else vice-versa - this.viewParentLookup = true; - // If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa - this.layoutParentLookup = true; + this.title = "v4"; // Module Entry Point - this.entryPoint = "v4"; + this.entryPoint = "v4"; // Inherit entry point from parent, so this will be /api/v1 - this.inheritEntryPoint = true; + this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "v4"; + this.modelNamespace = "v4"; // CF Mapping - this.cfmapping = "v4"; - // Auto-map models - this.autoMapModels = true; + this.cfmapping = "v4"; // Module Dependencies - this.dependencies = []; + this.dependencies = []; function configure(){ - // parent settings - parentSettings = {}; - - // module settings - stored in modules.name.settings - settings = {}; - - // Layout Settings - layoutSettings = { defaultLayout : "" }; - - // SES Routes: config/Router.cfc - - // Custom Declared Points - interceptorSettings = { customInterceptionPoints : "" }; - - // Custom Declared Interceptors - interceptors = []; - - // Binder Mappings - // binder.map("Alias").to("#moduleMapping#.model.MyService"); } /** diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 5ed113d..26a1cdc 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -7,29 +7,34 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v4"; property name="userService" inject="UserService@v4"; + this.prehandler_only = "show,delete,update"; + + any function preHandler( event, rc, prc, action, eventArguments ){ + try{ + validateOrFail( + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } + ); + } catch( any e ){ + arguments.exception = e; + this.onValidationException( argumentCollection = arguments ); + } + } /** * Returns a list of Rants */ any function index( event, rc, prc ){ - prc.response.setData( rantService.listArray() ); - // prc.response.setData( - // rantService.list().map( function( rant ) { - // return rant.getMemento(); - // }) - // ); + prc.response.setData( + rantService.list().map( ( rant ) => rant.getMemento() ) + ); } /** * Returns a single Rant - * */ function show( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) + prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); } /** @@ -37,78 +42,51 @@ component extends="coldbox.system.RestHandler" { * */ function delete( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); rantService.existsOrFail( rc.rantID ) - var result = rantService.delete( rc.rantID ); + rantService.delete( rc.rantID ); prc.response.addMessage( "Rant deleted" ); } /** * Creates a new Rant - * */ function create( event, rc, prc ){ - var validationResults = validateOrFail( + var rant = rantService.new(); + + validateOrFail( target = rc, - constraints = { - userID : { required : true, type : "numeric" }, - body : { required : true } - } + constraints = rant.constraints ); + userService.existsOrFail( rc.userID ); - var rant = rantService.new(); + rant.setBody( rc.body ); rant.setUserID( rc.userID ); - // var rant = populateModel( rantService.new() ); - validate( - target = rant, - constraints = { - body : { required : true }, - userID : { required : true, type : "numeric" } - } - ); - var result = rantService.create( rant ); - prc.response.setData( { "rantID" : result.getID() } ); + rantService.create( rant ); + + prc.response.setData( { "rantID" : rant.getID() } ); prc.response.addMessage( "Rant created" ); } /** * Updates an Existing Rant - * */ function update( event, rc, prc ){ - var validationResults = validateOrFail( + var rant = rantService.getOrFail( rc.rantId ); + + validateOrFail( target = rc, - constraints = { - rantID : { required : true, type : "numeric" }, - body : { required : true }, - userID : { required : true, type : "numeric" } - } + constraints = rant.constraints ); - rantService.existsOrFail( rc.rantID ); userService.existsOrFail( rc.userID ); - var rant = rantService.getOrFail( rc.rantID ); - // rant.setBody( rc.body ); - // rant.setUserID( rc.userID ); - // rant.setID( rc.rantID ) - - var rant = populateModel( model = rantService.new() ); - rant.setID( rc.rantID ) - validate( - target = rant, - constraints = { - id : { required : true, type : "numeric" }, - body : { required : true }, - userID : { required : true, type : "numeric" } - } - ); - var result = rantService.update( rant ); + rant.setBody( rc.body ); + rant.setUserID( rc.userID ); + + rantService.update( rant ); + prc.response.addMessage( "Rant Updated" ); } diff --git a/modules_app/api/modules_app/v4/models/BaseService.cfc b/modules_app/api/modules_app/v4/models/BaseService.cfc index ae8ee42..c0e5473 100644 --- a/modules_app/api/modules_app/v4/models/BaseService.cfc +++ b/modules_app/api/modules_app/v4/models/BaseService.cfc @@ -3,6 +3,10 @@ */ component accessors="true" { + // DI + property name="populator" inject="wirebox:populator"; + + // Properties property name="entityName"; property name="tableName"; property name="primaryKey"; @@ -46,11 +50,10 @@ component accessors="true" { where #getPrimaryKey()# = :id", { id : { - value : arguments[ 1 ], - type : "cf_sql_numeric" + value : arguments[ 1 ], + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } @@ -64,9 +67,11 @@ component accessors="true" { function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; - } else { - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } + throw( + type = "EntityNotFound", + message = "#entityName# Not Found" + ); } /** @@ -77,10 +82,13 @@ component accessors="true" { */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); - if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { - throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); + if ( !maybeEntity.isLoaded() ) { + throw( + type = "EntityNotFound", + message = "#getEntityName()# Not Found" + ); } return maybeEntity; } -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v4/models/Rant.cfc b/modules_app/api/modules_app/v4/models/Rant.cfc index aa71e5a..680db30 100644 --- a/modules_app/api/modules_app/v4/models/Rant.cfc +++ b/modules_app/api/modules_app/v4/models/Rant.cfc @@ -13,6 +13,11 @@ component accessors="true" { property name="modifiedDate" type="date"; property name="userID" type="string"; + // Validation Constraints + this.constraints = { + body : { required : true }, + userID : { required : true, type : "numeric" } + }; /** * Constructor @@ -35,6 +40,9 @@ component accessors="true" { return ( !isNull( variables.id ) && len( variables.id ) ); } + /** + * Marshall my object to data + */ function getMemento(){ return { "id" : getID(), diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index 1bc4d17..dda06ef 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -7,9 +7,6 @@ component accessors="true" { - // To populate objects from data - property name="populator" inject="wirebox:populator"; - /** * Constructor */ @@ -23,42 +20,41 @@ component return this; } + /** + * Let WireBox build new Rant objects for me + */ Rant function new() provider="Rant@v4"{ } - function list(){ + array function list(){ return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new (), rant ); + return populator.populateFromStruct( new(), rant ); } ); } - function listArray(){ + array function listArray(){ return queryExecute( "select * from rants ORDER BY createdDate DESC", - {}, - { returntype : "array" } - ) + {} + ).reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } Rant function get( required numeric rantID ){ - var q = queryExecute( + return queryExecute( "select * from rants where id = :rantID", { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } function delete( required numeric rantID ){ @@ -68,7 +64,7 @@ component { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } @@ -92,19 +88,19 @@ component { body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, userID : { value : "#arguments.rant.getuserID()#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" }, createdDate : { value : "#arguments.rant.getCreatedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -126,15 +122,15 @@ component { rantID : { value : "#arguments.rant.getID()#", - type : "cf_sql_integer" + cfsqltype : "cf_sql_integer" }, body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } diff --git a/modules_app/api/modules_app/v4/models/User.cfc b/modules_app/api/modules_app/v4/models/User.cfc new file mode 100644 index 0000000..b23eeab --- /dev/null +++ b/modules_app/api/modules_app/v4/models/User.cfc @@ -0,0 +1,42 @@ +/** + * I am a new User Object + */ +component accessors="true" { + + // Properties + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="modifiedDate" type="date"; + + + /** + * Constructor + */ + User function init(){ + return this; + } + + /** + * isLoaded + */ + boolean function isLoaded(){ + return ( !isNull( variables.id ) && len( variables.id ) ); + } + + /** + * Marshall my object to data + */ + function getMemento(){ + return { + "id" : getID(), + "username" : getUsername(), + "email" : getEmail(), + "createdDate" : dateFormat( getCreatedDate(), "long" ), + "modifiedDate" : dateFormat( getModifiedDate(), "long" ) + }; + } + +} diff --git a/modules_app/api/modules_app/v4/models/UserService.cfc b/modules_app/api/modules_app/v4/models/UserService.cfc index dc2de8d..26d8e31 100644 --- a/modules_app/api/modules_app/v4/models/UserService.cfc +++ b/modules_app/api/modules_app/v4/models/UserService.cfc @@ -20,6 +20,12 @@ component return this; } + /** + * Let WireBox build new Rant objects for me + */ + User function new() provider="User@v4"{ + } + User function get( required numeric userID ){ var q = queryExecute( "select * from users @@ -27,16 +33,10 @@ component { userID : { value : "#userID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } } diff --git a/tests/specs/integration/api-v1/EchoTests.cfc b/tests/specs/integration/api-v1/EchoTests.cfc index 8cdc9d8..81aa17b 100644 --- a/tests/specs/integration/api-v1/EchoTests.cfc +++ b/tests/specs/integration/api-v1/EchoTests.cfc @@ -16,7 +16,7 @@ *******************************************************************************/ component extends="coldbox.system.testing.BaseTestCase" - appMapping="/root" + { /*********************************** LIFE CYCLE Methods ***********************************/ diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index 5c351db..8d7a275 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V1 API Handler", function() { diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 0a01b9a..4dd2cd5 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V2 API Handler", function() { diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 61c1710..5101841 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V3 API Handler", function() { diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 6397b07..64ecc42 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V4 API Handler", function() { @@ -13,7 +13,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { then( "I will get a list of Rants", function() { var event = get( "/api/v4/rants" ); var returnedJSON = event.getRenderData().data; - debug( returnedJSON ); + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -28,19 +28,16 @@ component extends="tests.resources.BaseTest" appMapping="/" { scenario( "Get an individual Rant", function() { given( "I make a get call to /api/v4/rants/:rantID", function() { when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "x" var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -49,14 +46,13 @@ component extends="tests.resources.BaseTest" appMapping="/" { var rantID = "1" var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - debug( returnedJSON ); + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); } ); @@ -94,74 +90,67 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v4/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v4/rants", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v4/rants", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v4/rants", { "userID": "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v4/rants", { "userID": "5", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); @@ -175,7 +164,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -200,7 +188,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); - scenario( "Update a Rant", function() { given( "I make a get call to /api/v4/rants/:rantID", function() { when( "Using a get method", function() { @@ -226,97 +213,87 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v4/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v4/rants/#rantID#", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v4/rants/#rantID#", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v4/rants/#rantID#", { "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v4/rants/#rantID#", { "userID": "1", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = put( "/api/v4/rants/#rantID#", { "userID": "1", "body": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -331,7 +308,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -346,7 +322,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -355,7 +330,7 @@ component extends="tests.resources.BaseTest" appMapping="/" { var rantID = "7"; var event = put( "/api/v4/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); var returnedJSON = event.getRenderData().data; - debug( returnedJSON ); + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -406,19 +381,16 @@ component extends="tests.resources.BaseTest" appMapping="/" { } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -433,7 +405,6 @@ component extends="tests.resources.BaseTest" appMapping="/" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 0172958..f936c70 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V5 API Handler", function() { diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 41f2924..3602756 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" appMapping="/" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V6 API Handler", function() { From dbb17350b662e92e49fe8abcbf59f82b824e023f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 May 2020 12:40:15 -0500 Subject: [PATCH 18/75] v5 complete --- .../api/modules_app/v5/handlers/Rants.cfc | 74 +++++------- .../api/modules_app/v5/models/BaseEntity.cfc | 114 +++++++++--------- .../api/modules_app/v5/models/BaseService.cfc | 39 +++--- .../api/modules_app/v5/models/Rant.cfc | 25 ++-- .../api/modules_app/v5/models/RantService.cfc | 47 +++----- .../api/modules_app/v5/models/User.cfc | 23 ++++ .../api/modules_app/v5/models/UserService.cfc | 12 +- .../api/modules_app/v6/models/BaseService.cfc | 4 - tests/resources/BaseTest.cfc | 4 +- tests/specs/integration/api-v5/RantsTest.cfc | 110 ++++++----------- 10 files changed, 206 insertions(+), 246 deletions(-) create mode 100644 modules_app/api/modules_app/v5/models/User.cfc diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index e78f307..5b602fc 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -7,12 +7,26 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v5"; property name="userService" inject="UserService@v5"; + this.prehandler_only = "show,delete,update"; + any function preHandler( event, rc, prc, action, eventArguments ){ + try{ + validateOrFail( + target = rc, + constraints = { rantID : { required : true, type : "numeric" } } + ); + } catch( any e ){ + arguments.exception = e; + this.onValidationException( argumentCollection = arguments ); + } + } /** * Returns a list of Rants */ any function index( event, rc, prc ){ - prc.response.setData( rantService.listArray() ); + prc.response.setData( + rantService.list().map( ( rant ) => rant.getMemento() ) + ); } /** @@ -20,11 +34,9 @@ component extends="coldbox.system.RestHandler" { * */ function show( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + prc.response.setData( + rantService.getOrFail( rc.rantID ).getMemento() ); - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) } /** @@ -32,36 +44,25 @@ component extends="coldbox.system.RestHandler" { * */ function delete( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - rantService.getOrFail( rc.rantID ).delete(); + rantService + .getOrFail( rc.rantID ) + .delete(); + prc.response.addMessage( "Rant deleted" ); } /** * Creates a new Rant - * */ function create( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { - userID : { required : true, type : "numeric" }, - body : { required : true } - } - ); - userService.existsOrFail( rc.userID ); var result = rantService - .new( validationResults ) - .validateOrFail( { - body : { required : true }, - userID : { required : true, type : "numeric" } - } ) + .new( rc ) + .validateOrFail() .save(); - prc.response.setData( { "rantID" : result.getID() } ); - prc.response.addMessage( "Rant created" ); + + prc.response + .setData( { "rantID" : result.getID() } ) + .addMessage( "Rant created" ); } /** @@ -69,27 +70,12 @@ component extends="coldbox.system.RestHandler" { * */ function update( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { - rantID : { required : true, type : "numeric" }, - body : { required : true }, - userID : { required : true, type : "numeric" } - } - ); - userService.existsOrFail( rc.userID ); rantService .getOrFail( rc.rantID ) - .populate( validationResults ) - .setID( rc.rantID ) - .validateOrFail( - constraints = { - id : { required : true, type : "numeric" }, - body : { required : true }, - userID : { required : true, type : "numeric" } - } - ) + .populate( memento=rc, exclude="id" ) + .validateOrFail() .save(); + prc.response.addMessage( "Rant Updated" ); } diff --git a/modules_app/api/modules_app/v5/models/BaseEntity.cfc b/modules_app/api/modules_app/v5/models/BaseEntity.cfc index 070cb32..f76b79f 100644 --- a/modules_app/api/modules_app/v5/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v5/models/BaseEntity.cfc @@ -3,20 +3,46 @@ */ component accessors="true" { + // global properties property name="pk"; property name="entityName"; property name="serviceName"; property name="moduleName"; + property name="entityService"; // DI Injection - property name="wirebox" inject="wirebox"; - property name="coldbox" inject="coldbox"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + property name="coldbox" inject="coldbox"; + + // Basic memento settings + this.memento = { + // An array of the properties/relationships to include by default + defaultIncludes : [ "*" ], + // An array of properties/relationships to exclude by default + defaultExcludes : [], + // An array of properties/relationships to NEVER include + neverInclude : [ + "password", + "pk", + "entityName", + "serviceName", + "moduleName", + "entityService" + ], + // A struct of defaults for properties/relationships if they are null + defaults : {}, + // A struct of mapping functions for properties/relationships that can transform them + mappers : {} + } /** * Initialize Entity - stores information needed * * @pk The name of the primary key field in the entity * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @serviceName The name of the service that manages the entity + * @moduleName The name of the module for the objects */ function init( pk = "id", @@ -25,29 +51,37 @@ component accessors="true" { moduleName = "" ){ setPk( arguments.pk ); + if ( len( entityName ) ) { setEntityName( arguments.entityName ); } + if ( arguments.serviceName != "" ) { setServiceName( arguments.serviceName ); } else { setServiceName( arguments.entityName & "Service" ); } + setModuleName( arguments.moduleName ); if ( arguments.moduleName != "" ) { setServiceName( getServiceName() & "@" & arguments.moduleName ); } } + function onDIComplete(){ + variables.entityService = wirebox.getInstance( getServiceName() ); + } + /** * Verify if entity is loaded or not */ boolean function isLoaded(){ - return ( isNull( variables[ getPk() ] ) OR !len( variables[ getPk() ] ) ? false : true ); + return ( !structKeyExists( variables, getPk() ) OR !len( variables[ getPk() ] ) ? false : true ); } /** * Populate a model object from the request Collection or a passed in memento structure + * * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object * @include A list of keys to include in the population @@ -84,84 +118,50 @@ component accessors="true" { // json? if ( structKeyExists( arguments, "jsonstring" ) ) { - return wirebox.getObjectPopulator().populateFromJSON( argumentCollection = arguments ); + return variables.populator.populateFromJSON( argumentCollection = arguments ); } // XML else if ( structKeyExists( arguments, "xml" ) ) { - return wirebox.getObjectPopulator().populateFromXML( argumentCollection = arguments ); + return variables.populator.populateFromXML( argumentCollection = arguments ); } // Query else if ( structKeyExists( arguments, "qry" ) ) { - return wirebox.getObjectPopulator().populateFromQuery( argumentCollection = arguments ); + return variables.populator.populateFromQuery( argumentCollection = arguments ); } // Mementos else { // populate - return wirebox.getObjectPopulator().populateFromStruct( argumentCollection = arguments ); + return variables.populator.populateFromStruct( argumentCollection = arguments ); } } /** - * Validate an object or structure according to the constraints rules. - * @fields The fields to validate on the target. By default, it validates on all fields - * @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation - * @locale The i18n locale to use for validation messages - * @excludeFields The fields to exclude from the validation - * @includeFields The fields to include in the validation - * - * @return cbvalidation.model.result.IValidationResult - * @throws ValidationException error + * Validate an object or structure according to the constraints rules and throw an exception if the validation fails. + * The validation errors will be contained in the `extendedInfo` of the exception in JSON format */ - public struct function validateOrFail( - any constraints = {}, - string fields = "*", - string locale = "", - string excludeFields = "", - string includeFields = "" - ){ - var result = wirebox + function validateOrFail(){ + arguments.target = this; + return wirebox .getInstance( "ValidationManager@cbvalidation" ) - .validate( - target = this, - fields = arguments.fields, - constraints = arguments.constraints, - locale = arguments.locale, - excludeFields = arguments.excludeFields, - includeFields = arguments.includeFields - ); - if ( result.hasErrors() ) { - throw( - type = "ValidationException", - message = "The Model #getEntityName()# failed to pass validation", - extendedInfo = serializeJSON( result.getAllErrors() ) - ); - } - return this; + .validateOrFail( argumentCollection=arguments ); } + /** + * Save an entity + */ function save(){ if ( isLoaded() ) { - return wirebox.getInstance( "#getServiceName()#" ).update( this ); + return variables.entityService.update( this ); } else { - return wirebox.getInstance( "#getServiceName()#" ).create( this ); + return variables.entityService.create( this ); } } + /** + * Delete an entity + */ function delete(){ - return wirebox.getInstance( "#getServiceName()#" ).delete( this.getID() ); - } - - this.memento = { - // An array of the properties/relationships to include by default - defaultIncludes : [ "*" ], - // An array of properties/relationships to exclude by default - defaultExcludes : [], - // An array of properties/relationships to NEVER include - neverInclude : [], - // A struct of defaults for properties/relationships if they are null - defaults : {}, - // A struct of mapping functions for properties/relationships that can transform them - mappers : {} + return variables.entityService.delete( this.getID() ); } -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v5/models/BaseService.cfc b/modules_app/api/modules_app/v5/models/BaseService.cfc index 2b66251..42e42ff 100644 --- a/modules_app/api/modules_app/v5/models/BaseService.cfc +++ b/modules_app/api/modules_app/v5/models/BaseService.cfc @@ -3,6 +3,11 @@ */ component accessors="true" { + // DI + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + + // Properties property name="entityName"; property name="tableName"; property name="primaryKey"; @@ -43,15 +48,11 @@ component accessors="true" { * @data Data to populate the new Entity with */ function new( struct data = {} ){ - // if( data.isEmpty() ){ - - // } else { - var modelName = getEntityName(); - if ( getModuleName() != "" ) { - modelName = modelName & "@" & getModuleName(); - } - return populator.populateFromStruct( target = wireBox.getInstance( "#modelName#" ), memento = arguments.data ) - // } + var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); + return populator.populateFromStruct( + target = wireBox.getInstance( modelName ), + memento = arguments.data + ); } /** @@ -66,11 +67,10 @@ component accessors="true" { where #getPrimaryKey()# = :id", { id : { - value : arguments[ 1 ], - type : "cf_sql_numeric" + value : arguments[ 1 ], + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } @@ -84,9 +84,11 @@ component accessors="true" { function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; - } else { - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } + throw( + type = "EntityNotFound", + message = "#entityName# Not Found" + ); } /** @@ -97,8 +99,11 @@ component accessors="true" { */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); - if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { - throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); + if ( !maybeEntity.isLoaded() ) { + throw( + type = "EntityNotFound", + message = "#getEntityName()# Not Found" + ); } return maybeEntity; } diff --git a/modules_app/api/modules_app/v5/models/Rant.cfc b/modules_app/api/modules_app/v5/models/Rant.cfc index 2c46252..e0c1ad1 100644 --- a/modules_app/api/modules_app/v5/models/Rant.cfc +++ b/modules_app/api/modules_app/v5/models/Rant.cfc @@ -13,6 +13,19 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="modifiedDate" type="date"; property name="userID" type="string"; + // Validation Constraints + this.constraints = { + body : { required : true }, + userID : { + required : true, + type : "numeric", + udf : ( value, target ) => { + if( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + return userService.exists( arguments.value ); + }, + udfMessage : "User ({rejectedValue}) not found" + } + }; /** * Constructor @@ -29,14 +42,4 @@ component extends="v5.models.BaseEntity" accessors="true" { return userService.get( getUserID() ); } - // function getMemento() { - // return { - // "id" = getID(), - // "body" = getBody(), - // "createdDate" = dateFormat( getCreatedDate(), "long" ), - // "modifiedDate" = dateFormat( getModifiedDate(), "long" ), - // "userId" = getUserID() - // }; - // } - -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index b50b087..8f59a44 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -7,10 +7,6 @@ component accessors="true" { - // DI Injection - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; - /** * Constructor */ @@ -28,35 +24,31 @@ component return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new (), rant ); + return populator.populateFromStruct( new(), rant ); } ); } function listArray(){ return queryExecute( "select * from rants ORDER BY createdDate DESC", - {}, - { returntype : "array" } - ) + {} + ).reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } Rant function get( required numeric rantID ){ - var q = queryExecute( + return queryExecute( "select * from rants where id = :rantID", { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } function delete( required numeric rantID ){ @@ -66,7 +58,7 @@ component { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } @@ -90,19 +82,19 @@ component { body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, userID : { value : "#arguments.rant.getuserID()#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" }, createdDate : { value : "#arguments.rant.getCreatedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -124,20 +116,21 @@ component { rantID : { value : "#arguments.rant.getID()#", - type : "cf_sql_integer" + cfsqltype : "cf_sql_integer" }, body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); - return local.result; + + return arguments.rant; } } diff --git a/modules_app/api/modules_app/v5/models/User.cfc b/modules_app/api/modules_app/v5/models/User.cfc new file mode 100644 index 0000000..bd7495a --- /dev/null +++ b/modules_app/api/modules_app/v5/models/User.cfc @@ -0,0 +1,23 @@ +/** + * I am a new User Object + */ +component extends="v5.models.BaseEntity" accessors="true" { + + // Properties + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="modifiedDate" type="date"; + + + /** + * Constructor + */ + User function init(){ + super.init( entityName = "User", moduleName = "v5" ); + return this; + } + +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v5/models/UserService.cfc b/modules_app/api/modules_app/v5/models/UserService.cfc index ca72884..2e5c166 100644 --- a/modules_app/api/modules_app/v5/models/UserService.cfc +++ b/modules_app/api/modules_app/v5/models/UserService.cfc @@ -27,16 +27,10 @@ component { userID : { value : "#userID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } } diff --git a/modules_app/api/modules_app/v6/models/BaseService.cfc b/modules_app/api/modules_app/v6/models/BaseService.cfc index 33ab744..0621246 100644 --- a/modules_app/api/modules_app/v6/models/BaseService.cfc +++ b/modules_app/api/modules_app/v6/models/BaseService.cfc @@ -43,15 +43,11 @@ component accessors="true" { * @data Data to populate the new Entity with */ function new( struct data = {} ){ - // if( data.isEmpty() ){ - - // } else { var modelName = getEntityName(); if ( getModuleName() != "" ) { modelName = modelName & "@" & getModuleName(); } return populator.populateFromStruct( target = wireBox.getInstance( "#modelName#" ), memento = arguments.data ) - // } } /** diff --git a/tests/resources/BaseTest.cfc b/tests/resources/BaseTest.cfc index 6dcd213..e3b153a 100644 --- a/tests/resources/BaseTest.cfc +++ b/tests/resources/BaseTest.cfc @@ -35,13 +35,13 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { } catch ( any e ) { expectation.message = "[#expecation.actual#] does not have a getStatusCode method."; - debug( expectation.actual ); + debug( expectation.actual.getResponse() ); return false; } if ( statusCode != args.statusCode ) { expectation.message = "#args.message#. Received incorrect status code. Expected [#args.statusCode#]. Received [#statusCode#]."; - debug( expectation.actual ); + debug( expectation.actual.getResponse() ); return false; } diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index f936c70..22958fd 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V5 API Handler", function() { @@ -13,6 +13,7 @@ component extends="tests.resources.BaseTest" { then( "I will get a list of Rants", function() { var event = get( "/api/v5/rants" ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -27,19 +28,16 @@ component extends="tests.resources.BaseTest" { scenario( "Get an individual Rant", function() { given( "I make a get call to /api/v5/rants/:rantID", function() { when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "x" var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -48,13 +46,13 @@ component extends="tests.resources.BaseTest" { var rantID = "1" var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); } ); @@ -92,88 +90,80 @@ component extends="tests.resources.BaseTest" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", { "userID": "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", { "userID": "5", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v5/rants", { "body": "xsxswxws", "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -198,7 +188,6 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function() { given( "I make a get call to /api/v5/rants/:rantID", function() { when( "Using a get method", function() { @@ -223,113 +212,88 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", {} ); - var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); - } ); - } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v5/rants/#rantID#", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v5/rants/#rantID#", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v5/rants/#rantID#", { "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v5/rants/#rantID#", { "userID": "1", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = put( "/api/v5/rants/#rantID#", { "userID": "1", "body": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v5/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -344,7 +308,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -353,6 +316,7 @@ component extends="tests.resources.BaseTest" { var rantID = "7"; var event = put( "/api/v5/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -403,19 +367,16 @@ component extends="tests.resources.BaseTest" { } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -430,7 +391,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -441,8 +401,8 @@ component extends="tests.resources.BaseTest" { setup(); var rantID = returnedJSON.data.rantID; var event2 = delete( "/api/v5/rants/#rantID#" ); + var returnedJSON2 = event2.getRenderData().data; - debug( returnedJSON2 ); expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); expect( returnedJSON2.error ).toBeFalse(); expect( event2.getStatusCode() ).toBe( 200 ); From b674f04b5fd025bc8c61586c27fad9dd59a15349 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 May 2020 13:10:02 -0500 Subject: [PATCH 19/75] finalized v6 --- config/Coldbox.cfc | 4 +- .../api/modules_app/v6/config/Router.cfc | 2 +- .../api/modules_app/v6/handlers/Rants.cfc | 93 +++++++------- .../api/modules_app/v6/models/BaseEntity.cfc | 118 +++++++++--------- .../api/modules_app/v6/models/BaseService.cfc | 61 ++++----- .../api/modules_app/v6/models/Rant.cfc | 36 +++--- .../api/modules_app/v6/models/RantService.cfc | 53 ++++---- .../api/modules_app/v6/models/User.cfc | 23 ++++ .../api/modules_app/v6/models/UserService.cfc | 18 +-- resources/apidocs/_responses/rant.404.json | 4 +- resources/apidocs/_responses/user.404.json | 2 +- .../{example.412.json => example.400.json} | 0 .../api-v6/Rants/create/requestBody.json | 4 +- .../api-v6/Rants/create/responses.json | 6 +- .../{example.412.json => example.400.json} | 0 .../api-v6/Rants/update/requestBody.json | 4 +- .../api-v6/Rants/update/responses.json | 6 +- tests/specs/integration/api-v6/RantsTest.cfc | 112 ++++++----------- 18 files changed, 244 insertions(+), 302 deletions(-) create mode 100644 modules_app/api/modules_app/v6/models/User.cfc rename resources/apidocs/api-v6/Rants/create/{example.412.json => example.400.json} (100%) rename resources/apidocs/api-v6/Rants/update/{example.412.json => example.400.json} (100%) diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 60a7fa3..cee1193 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -42,8 +42,8 @@ invalidEventHandler : "", customErrorTemplate : "", // Application Aspects - handlerCaching : false, - eventCaching : false, + handlerCaching : true, + eventCaching : true, viewCaching : false, // Will automatically do a mapDirectory() on your `models` for you. autoMapModels : true, diff --git a/modules_app/api/modules_app/v6/config/Router.cfc b/modules_app/api/modules_app/v6/config/Router.cfc index da45da4..adfd4cd 100644 --- a/modules_app/api/modules_app/v6/config/Router.cfc +++ b/modules_app/api/modules_app/v6/config/Router.cfc @@ -3,7 +3,7 @@ component { function configure(){ resources( resource = "rants", - parameterName = "rantID", + parameterName = "rantID-numeric", except = [ "new", "edit" ] ); diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index 0478fd8..9d94708 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -1,103 +1,98 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` */ -component displayName="Rants" extends="coldbox.system.RestHandler" { +component extends="coldbox.system.RestHandler" { // DI property name="rantService" inject="RantService@v6"; property name="userService" inject="UserService@v6"; - /** - * @route (GET) /api/v6/rants + * @x-route (GET) /api/v6/rants * * Returns a list of Rants * - * @response-200 /resources/apidocs/api-v6/Rants/index/responses.json##200 + * @response-200 ~api-v6/Rants/index/responses.json##200 */ - any function index( event, rc, prc ){ - prc.response.setData( rantService.listArray() ); + any function index( event, rc, prc ) cache=true cacheTimeout=60{ + prc.response.setData( + rantService.list().map( ( rant ) => rant.getMemento() ) + ); } /** - * @route (GET) /api/v6/rants/:rantID + * @x-route (GET) /api/v6/rants/:rantID * * Display a single Rant. * - * @x-parameters /resources/apidocs/api-v6/Rants/show/parameters.json##parameters - * @response-200 /resources/apidocs/api-v6/Rants/show/responses.json##200 - * @response-404 /resources/apidocs/_responses/rant.404.json + * @x-parameters ~api-v6/Rants/show/parameters.json##parameters + * @response-200 ~api-v6/Rants/show/responses.json##200 + * @response-404 ~_responses/rant.404.json */ - function show( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + function show( event, rc, prc ) cache=true cacheTimeout=60{ + prc.response.setData( + rantService.getOrFail( rc.rantID ).getMemento() ); - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ) } /** - * @route (DELETE) /api/v6/rants/:rantID + * @x-route (DELETE) /api/v6/rants/:rantID * * Delete a single Rant. * - * @x-parameters /resources/apidocs/api-v6/Rants/delete/parameters.json##parameters - * @response-200 /resources/apidocs/api-v6/Rants/delete/responses.json##200 - * @response-404 /resources/apidocs/_responses/rant.404.json + * @x-parameters ~api-v6/Rants/delete/parameters.json##parameters + * @response-200 ~api-v6/Rants/delete/responses.json##200 + * @response-404 ~_responses/rant.404.json */ function delete( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - rantService.getOrFail( rc.rantID ).delete(); + rantService + .getOrFail( rc.rantID ) + .delete(); + prc.response.addMessage( "Rant deleted" ); } /** - * @route (POST) /api/v1/rants + * @x-route (POST) /api/v1/rants * * Creates a new Rant. * - * @requestBody /resources/apidocs/api-v6/Rants/create/requestBody.json - * @response-200 /resources/apidocs/api-v6/Rants/create/responses.json##200 - * @response-412 /resources/apidocs/api-v6/Rants/create/responses.json##412 + * @requestBody ~api-v6/Rants/create/requestBody.json + * @response-200 ~api-v6/Rants/create/responses.json##200 + * @response-400 ~api-v6/Rants/create/responses.json##400 */ function create( event, rc, prc ){ - var validationResults = validateOrFail( target = rc, constraints = rantService.getConstraints() ); - userService.existsOrFail( rc.userID ); var result = rantService - .new( validationResults ) - .validateOrFail( rantService.getConstraints() ) + .new( rc ) + .validateOrFail() .save(); - prc.response.setData( { "rantID" : result.getID() } ); - prc.response.addMessage( "Rant created" ); + + prc.response + .setData( { "rantID" : result.getID() } ) + .addMessage( "Rant created" ); + + getCache( "template" ).clearAllEvents(); } /** - * @route (PUT) /api/v1/rants/:rantID + * @x-route (PUT) /api/v1/rants/:rantID * * Update an existing Rant. * - * @requestBody /resources/apidocs/api-v6/Rants/update/requestBody.json - * @response-200 /resources/apidocs/api-v6/Rants/update/responses.json##200 - * @response-412 /resources/apidocs/api-v6/Rants/update/responses.json##412 + * @requestBody ~api-v6/Rants/update/requestBody.json + * @response-200 ~api-v6/Rants/update/responses.json##200 + * @response-400 ~api-v6/Rants/update/responses.json##400 */ function update( event, rc, prc ){ - var validationResults = validateOrFail( - target = rc, - constraints = rantService.addConstraints( { rantID : { required : true, type : "numeric" } } ) - ); - userService.existsOrFail( rc.userID ); rantService .getOrFail( rc.rantID ) - .populate( validationResults ) - .setID( rc.rantID ) - .validateOrFail( - constraints = rantService.addConstraints( { ID : { required : true, type : "numeric" } } ) - ) + .populate( memento=rc, exclude="id" ) + .validateOrFail() .save(); + prc.response.addMessage( "Rant Updated" ); + + getCache( "template" ).clearAllEvents(); } -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v6/models/BaseEntity.cfc b/modules_app/api/modules_app/v6/models/BaseEntity.cfc index 1a19b66..f76b79f 100644 --- a/modules_app/api/modules_app/v6/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v6/models/BaseEntity.cfc @@ -3,20 +3,46 @@ */ component accessors="true" { + // global properties property name="pk"; property name="entityName"; property name="serviceName"; property name="moduleName"; + property name="entityService"; // DI Injection - property name="wirebox" inject="wirebox"; - property name="coldbox" inject="coldbox"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + property name="coldbox" inject="coldbox"; + + // Basic memento settings + this.memento = { + // An array of the properties/relationships to include by default + defaultIncludes : [ "*" ], + // An array of properties/relationships to exclude by default + defaultExcludes : [], + // An array of properties/relationships to NEVER include + neverInclude : [ + "password", + "pk", + "entityName", + "serviceName", + "moduleName", + "entityService" + ], + // A struct of defaults for properties/relationships if they are null + defaults : {}, + // A struct of mapping functions for properties/relationships that can transform them + mappers : {} + } /** * Initialize Entity - stores information needed * * @pk The name of the primary key field in the entity * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @serviceName The name of the service that manages the entity + * @moduleName The name of the module for the objects */ function init( pk = "id", @@ -25,29 +51,37 @@ component accessors="true" { moduleName = "" ){ setPk( arguments.pk ); + if ( len( entityName ) ) { setEntityName( arguments.entityName ); } + if ( arguments.serviceName != "" ) { setServiceName( arguments.serviceName ); } else { setServiceName( arguments.entityName & "Service" ); } + setModuleName( arguments.moduleName ); if ( arguments.moduleName != "" ) { setServiceName( getServiceName() & "@" & arguments.moduleName ); } } + function onDIComplete(){ + variables.entityService = wirebox.getInstance( getServiceName() ); + } + /** * Verify if entity is loaded or not */ boolean function isLoaded(){ - return ( isNull( variables[ getPk() ] ) OR !len( variables[ getPk() ] ) ? false : true ); + return ( !structKeyExists( variables, getPk() ) OR !len( variables[ getPk() ] ) ? false : true ); } /** * Populate a model object from the request Collection or a passed in memento structure + * * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object * @include A list of keys to include in the population @@ -84,88 +118,50 @@ component accessors="true" { // json? if ( structKeyExists( arguments, "jsonstring" ) ) { - return wirebox.getObjectPopulator().populateFromJSON( argumentCollection = arguments ); + return variables.populator.populateFromJSON( argumentCollection = arguments ); } // XML else if ( structKeyExists( arguments, "xml" ) ) { - return wirebox.getObjectPopulator().populateFromXML( argumentCollection = arguments ); + return variables.populator.populateFromXML( argumentCollection = arguments ); } // Query else if ( structKeyExists( arguments, "qry" ) ) { - return wirebox.getObjectPopulator().populateFromQuery( argumentCollection = arguments ); + return variables.populator.populateFromQuery( argumentCollection = arguments ); } // Mementos else { // populate - return wirebox.getObjectPopulator().populateFromStruct( argumentCollection = arguments ); + return variables.populator.populateFromStruct( argumentCollection = arguments ); } } /** - * Validate an object or structure according to the constraints rules. - * @fields The fields to validate on the target. By default, it validates on all fields - * @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation - * @locale The i18n locale to use for validation messages - * @excludeFields The fields to exclude from the validation - * @includeFields The fields to include in the validation - * - * @return cbvalidation.model.result.IValidationResult - * @throws ValidationException error + * Validate an object or structure according to the constraints rules and throw an exception if the validation fails. + * The validation errors will be contained in the `extendedInfo` of the exception in JSON format */ - public struct function validateOrFail( - any constraints = {}, - string fields = "*", - string locale = "", - string excludeFields = "", - string includeFields = "" - ){ - var result = wirebox + function validateOrFail(){ + arguments.target = this; + return wirebox .getInstance( "ValidationManager@cbvalidation" ) - .validate( - target = this, - fields = arguments.fields, - constraints = arguments.constraints, - locale = arguments.locale, - excludeFields = arguments.excludeFields, - includeFields = arguments.includeFields - ); - if ( result.hasErrors() ) { - throw( - type = "ValidationException", - message = "The Model #getEntityName()# failed to pass validation", - extendedInfo = serializeJSON( result.getAllErrors() ) - ); - } - return this; + .validateOrFail( argumentCollection=arguments ); } + /** + * Save an entity + */ function save(){ if ( isLoaded() ) { - return wirebox.getInstance( "#getServiceName()#" ).update( this ); + return variables.entityService.update( this ); } else { - return wirebox.getInstance( "#getServiceName()#" ).create( this ); + return variables.entityService.create( this ); } } + /** + * Delete an entity + */ function delete(){ - return wirebox.getInstance( "#getServiceName()#" ).delete( this.getID() ); - } - - this.memento = { - // An array of the properties/relationships to include by default - defaultIncludes : [ "*" ], - // An array of properties/relationships to exclude by default - defaultExcludes : [], - // An array of properties/relationships to NEVER include - neverInclude : [ - "entityName", - "pk", - "serviceName", - "moduleName" - ], // A struct of defaults for properties/relationships if they are null - defaults : {}, - // A struct of mapping functions for properties/relationships that can transform them - mappers : {} + return variables.entityService.delete( this.getID() ); } -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v6/models/BaseService.cfc b/modules_app/api/modules_app/v6/models/BaseService.cfc index 0621246..42e42ff 100644 --- a/modules_app/api/modules_app/v6/models/BaseService.cfc +++ b/modules_app/api/modules_app/v6/models/BaseService.cfc @@ -3,6 +3,11 @@ */ component accessors="true" { + // DI + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + + // Properties property name="entityName"; property name="tableName"; property name="primaryKey"; @@ -43,11 +48,11 @@ component accessors="true" { * @data Data to populate the new Entity with */ function new( struct data = {} ){ - var modelName = getEntityName(); - if ( getModuleName() != "" ) { - modelName = modelName & "@" & getModuleName(); - } - return populator.populateFromStruct( target = wireBox.getInstance( "#modelName#" ), memento = arguments.data ) + var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); + return populator.populateFromStruct( + target = wireBox.getInstance( modelName ), + memento = arguments.data + ); } /** @@ -62,11 +67,10 @@ component accessors="true" { where #getPrimaryKey()# = :id", { id : { - value : arguments[ 1 ], - type : "cf_sql_numeric" + value : arguments[ 1 ], + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } + } ).len() ) } @@ -80,9 +84,11 @@ component accessors="true" { function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; - } else { - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } + throw( + type = "EntityNotFound", + message = "#entityName# Not Found" + ); } /** @@ -93,36 +99,13 @@ component accessors="true" { */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); - if ( isNull( maybeEntity ) || !maybeEntity.isLoaded() ) { - throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); + if ( !maybeEntity.isLoaded() ) { + throw( + type = "EntityNotFound", + message = "#getEntityName()# Not Found" + ); } return maybeEntity; } - /** - * Helper to get Entity Constraints - * - * @constraintsKeyName The name of the variable with the entity constraints inside of the entity. Defaults to the convention of `constraints` - * - * @return a CBValidation compliant struct of Entity Constraints - */ - function getConstraints( string constraintsKeyName = "constraints" ){ - return new ( {} )[ arguments.constraintsKeyName ]; - } - - - /** - * Helper to add a structure of Constraints into the existing entity constraints and return the combined struct - * - * @newConstraints The new struct full of constraints to add - * @constraintsKeyName The name of the variable with the entity constraints inside of the entity. Defaults to the convention of `constraints` - * - * @return a CBValidation compliant struct of Entity Constraints - */ - function addConstraints( newConstraints = {}, constraintsKeyName = "constraints" ){ - var constraints = getConstraints( arguments.constraintsKeyName ); - constraints.append( arguments.newConstraints ); - return constraints; - } - } diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index 3efb2ce..e0c1ad1 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -1,10 +1,10 @@ /** * I am a new Rant Object */ -component extends="v6.models.BaseEntity" accessors="true" { +component extends="v5.models.BaseEntity" accessors="true" { // DI - property name="userService" inject="UserService@v6"; + property name="userService" inject="UserService@v5"; // Properties property name="id" type="string"; @@ -13,20 +13,28 @@ component extends="v6.models.BaseEntity" accessors="true" { property name="modifiedDate" type="date"; property name="userID" type="string"; + // Validation Constraints + this.constraints = { + body : { required : true }, + userID : { + required : true, + type : "numeric", + udf : ( value, target ) => { + if( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + return userService.exists( arguments.value ); + }, + udfMessage : "User ({rejectedValue}) not found" + } + }; /** * Constructor */ Rant function init(){ - super.init( entityName = "rant", moduleName = "v6" ); + super.init( entityName = "rant", moduleName = "v5" ); return this; } - this.constraints = { - userID : { required : true, type : "numeric" }, - body : { required : true } - }; - /** * getUser */ @@ -34,14 +42,4 @@ component extends="v6.models.BaseEntity" accessors="true" { return userService.get( getUserID() ); } - // function getMemento() { - // return { - // "id" = getID(), - // "body" = getBody(), - // "createdDate" = dateFormat( getCreatedDate(), "long" ), - // "modifiedDate" = dateFormat( getModifiedDate(), "long" ), - // "userId" = getUserID() - // }; - // } - -} +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index b12b61b..8f59a44 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -1,16 +1,12 @@ /** - * I am the Rant Service v6 + * I am the Rant Service v5 */ component - extends="v6.models.BaseService" + extends="v5.models.BaseService" singleton accessors="true" { - // DI Injection - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; - /** * Constructor */ @@ -19,7 +15,7 @@ component entityName = "rant", tableName = "rants", parameterName = "rantID", - moduleName = "v6" + moduleName = "v5" ) return this; } @@ -28,35 +24,31 @@ component return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new (), rant ); + return populator.populateFromStruct( new(), rant ); } ); } function listArray(){ return queryExecute( "select * from rants ORDER BY createdDate DESC", - {}, - { returntype : "array" } - ) + {} + ).reduce( ( result, row ) => { + result.append( row ); + return result; + }, [] ); } Rant function get( required numeric rantID ){ - var q = queryExecute( + return queryExecute( "select * from rants where id = :rantID", { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } function delete( required numeric rantID ){ @@ -66,7 +58,7 @@ component { rantID : { value : "#rantID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } @@ -90,19 +82,19 @@ component { body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, userID : { value : "#arguments.rant.getuserID()#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" }, createdDate : { value : "#arguments.rant.getCreatedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -124,20 +116,21 @@ component { rantID : { value : "#arguments.rant.getID()#", - type : "cf_sql_integer" + cfsqltype : "cf_sql_integer" }, body : { value : "#arguments.rant.getBody()#", - type : "cf_sql_longvarchar" + cfsqltype : "cf_sql_longvarchar" }, modifiedDate : { value : "#arguments.rant.getModifiedDate()#", - type : "cf_sql_timestamp" + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); - return local.result; + + return arguments.rant; } } diff --git a/modules_app/api/modules_app/v6/models/User.cfc b/modules_app/api/modules_app/v6/models/User.cfc new file mode 100644 index 0000000..bd7495a --- /dev/null +++ b/modules_app/api/modules_app/v6/models/User.cfc @@ -0,0 +1,23 @@ +/** + * I am a new User Object + */ +component extends="v5.models.BaseEntity" accessors="true" { + + // Properties + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="modifiedDate" type="date"; + + + /** + * Constructor + */ + User function init(){ + super.init( entityName = "User", moduleName = "v5" ); + return this; + } + +} \ No newline at end of file diff --git a/modules_app/api/modules_app/v6/models/UserService.cfc b/modules_app/api/modules_app/v6/models/UserService.cfc index 8665ccd..2e5c166 100644 --- a/modules_app/api/modules_app/v6/models/UserService.cfc +++ b/modules_app/api/modules_app/v6/models/UserService.cfc @@ -1,8 +1,8 @@ /** - * I am the User Service v6 + * I am the User Service v5 */ component - extends="v6.models.BaseService" + extends="v5.models.BaseService" singleton accessors="true" { @@ -15,7 +15,7 @@ component entityName = "user", tableName = "users", parameterName = "userID", - moduleName = "v6" + moduleName = "v5" ) return this; } @@ -27,16 +27,10 @@ component { userID : { value : "#userID#", - type : "cf_sql_numeric" + cfsqltype : "cf_sql_numeric" } - }, - { returntype : "array" } - ); - if ( q.len() ) { - return populator.populateFromStruct( new (), q[ 1 ] ); - } else { - return new () - } + } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); } } diff --git a/resources/apidocs/_responses/rant.404.json b/resources/apidocs/_responses/rant.404.json index d1841fa..e2c2b17 100644 --- a/resources/apidocs/_responses/rant.404.json +++ b/resources/apidocs/_responses/rant.404.json @@ -7,7 +7,7 @@ "error": true, "pagination": {}, "messages": [ - "Rant Not Found", + "Rant Not Found" ] }, "schema": { @@ -25,7 +25,7 @@ } }, "data": { - "description": "Empty response for 412", + "description": "Empty response", "type": "string" } } diff --git a/resources/apidocs/_responses/user.404.json b/resources/apidocs/_responses/user.404.json index 67dfa15..cb7cbbc 100644 --- a/resources/apidocs/_responses/user.404.json +++ b/resources/apidocs/_responses/user.404.json @@ -7,7 +7,7 @@ "error": true, "pagination": {}, "messages": [ - "User Not Found", + "User Not Found" ] }, "schema": { diff --git a/resources/apidocs/api-v6/Rants/create/example.412.json b/resources/apidocs/api-v6/Rants/create/example.400.json similarity index 100% rename from resources/apidocs/api-v6/Rants/create/example.412.json rename to resources/apidocs/api-v6/Rants/create/example.400.json diff --git a/resources/apidocs/api-v6/Rants/create/requestBody.json b/resources/apidocs/api-v6/Rants/create/requestBody.json index 16233e7..516c1d5 100644 --- a/resources/apidocs/api-v6/Rants/create/requestBody.json +++ b/resources/apidocs/api-v6/Rants/create/requestBody.json @@ -7,7 +7,7 @@ "type": "object", "required": [ "body", - "userID", + "userID" ], "properties": { "body": { @@ -17,7 +17,7 @@ "userID": { "description": "The id corresponding to the User who sent this Rant", "type": "integer" - }, + } }, "example": { "body": "I love to get up on my SoapBox and Rant away", diff --git a/resources/apidocs/api-v6/Rants/create/responses.json b/resources/apidocs/api-v6/Rants/create/responses.json index 534c649..1175a38 100644 --- a/resources/apidocs/api-v6/Rants/create/responses.json +++ b/resources/apidocs/api-v6/Rants/create/responses.json @@ -36,12 +36,12 @@ } } }, - "412": { + "400": { "description": "Validation failed trying to create a Rant.", "content": { "application/json": { "example": { - "$ref": "example.412.json" + "$ref": "example.400.json" }, "schema": { "type": "object", @@ -58,7 +58,7 @@ } }, "data": { - "description": "Empty response for 412", + "description": "Empty response for 400", "type": "string" } } diff --git a/resources/apidocs/api-v6/Rants/update/example.412.json b/resources/apidocs/api-v6/Rants/update/example.400.json similarity index 100% rename from resources/apidocs/api-v6/Rants/update/example.412.json rename to resources/apidocs/api-v6/Rants/update/example.400.json diff --git a/resources/apidocs/api-v6/Rants/update/requestBody.json b/resources/apidocs/api-v6/Rants/update/requestBody.json index 88dd4e8..1816dde 100644 --- a/resources/apidocs/api-v6/Rants/update/requestBody.json +++ b/resources/apidocs/api-v6/Rants/update/requestBody.json @@ -7,7 +7,7 @@ "type": "object", "required": [ "body", - "userID", + "userID" ], "properties": { "body": { @@ -17,7 +17,7 @@ "userID": { "description": "The id corresponding to the User who sent this Rant", "type": "integer" - }, + } }, "example": { "body": "I love to get up on my SoapBox and Rant away", diff --git a/resources/apidocs/api-v6/Rants/update/responses.json b/resources/apidocs/api-v6/Rants/update/responses.json index dca3c8c..bf10df5 100644 --- a/resources/apidocs/api-v6/Rants/update/responses.json +++ b/resources/apidocs/api-v6/Rants/update/responses.json @@ -29,12 +29,12 @@ } } }, - "412": { + "400": { "description": "Validation failed trying to update the Rant.", "content": { "application/json": { "example": { - "$ref": "example.412.json" + "$ref": "example.400.json" }, "schema": { "type": "object", @@ -51,7 +51,7 @@ } }, "data": { - "description": "Empty response for 412", + "description": "Empty response for 400", "type": "string" } } diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 3602756..c520a9e 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -1,4 +1,4 @@ -component extends="tests.resources.BaseTest" { +component extends="tests.resources.BaseTest" { function run() { describe( "Rants V6 API Handler", function() { @@ -13,6 +13,7 @@ component extends="tests.resources.BaseTest" { then( "I will get a list of Rants", function() { var event = get( "/api/v6/rants" ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -27,19 +28,16 @@ component extends="tests.resources.BaseTest" { scenario( "Get an individual Rant", function() { given( "I make a get call to /api/v6/rants/:rantID", function() { when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "x" var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -48,13 +46,13 @@ component extends="tests.resources.BaseTest" { var rantID = "1" var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); } ); @@ -92,88 +90,80 @@ component extends="tests.resources.BaseTest" { } ); when( "Including no userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", { "userID": "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", { "userID": "5", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { + then( "I will get a 400 error", function() { var event = post( "/api/v6/rants", { "body": "xsxswxws", "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -198,7 +188,6 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function() { given( "I make a get call to /api/v6/rants/:rantID", function() { when( "Using a get method", function() { @@ -223,113 +212,88 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", {} ); - var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); - } ); - } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v6/rants/#rantID#", { "userID": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); } ); when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v6/rants/#rantID#", { "userID": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v6/rants/#rantID#", { "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; + then( "I will get a 400 error", function() { + var rantID = "4"; var event = put( "/api/v6/rants/#rantID#", { "userID": "1", "body": "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = put( "/api/v6/rants/#rantID#", { "userID": "1", "body": "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { + then( "I will get a 400 error", function() { var rantID = "7"; var event = put( "/api/v6/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -344,7 +308,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -353,6 +316,7 @@ component extends="tests.resources.BaseTest" { var rantID = "7"; var event = put( "/api/v6/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); var returnedJSON = event.getRenderData().data; + //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -403,19 +367,16 @@ component extends="tests.resources.BaseTest" { } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { + then( "I will get a 400 error", function() { var rantID = "abc"; var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatusCode( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" - ); } ); } ); @@ -430,7 +391,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -441,8 +401,8 @@ component extends="tests.resources.BaseTest" { setup(); var rantID = returnedJSON.data.rantID; var event2 = delete( "/api/v6/rants/#rantID#" ); + var returnedJSON2 = event2.getRenderData().data; - debug( returnedJSON2 ); expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); expect( returnedJSON2.error ).toBeFalse(); expect( event2.getStatusCode() ).toBe( 200 ); @@ -458,4 +418,4 @@ component extends="tests.resources.BaseTest" { } ); } -} +} \ No newline at end of file From 93f2232a14a332359f11b44f07d609b15d53d5b2 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 19 May 2020 09:45:21 -0500 Subject: [PATCH 20/75] updated readme --- readme.md | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index 4022f16..a1efb8f 100644 --- a/readme.md +++ b/readme.md @@ -4,38 +4,30 @@ This repo is a demo for our presentation on building modern functional & fluent ## App Setup -### Modules needed - -This app works with CommandBox, it also uses a couple of CommandBox system modules which are useful in most CommandBox projects ( in box.json for simplicity ): - -- CFConfig CLI - https://www.forgebox.io/view/commandbox-cfconfig -- CommandBox dotenv - https://www.forgebox.io/view/commandbox-dotenv -- CFFormat - https://www.forgebox.io/view/commandbox-cfformat -- -Recommened but not required: +### Install Dependencies -- commandbox-cflint - https://www.forgebox.io/view/commandbox-cflint +Just use CommandBox and install them: `box install` ### Database setup -The database needed for this is MySQL 5.7. The SQL file for this project is located in the /workbench/database folder. Please use that to seed your database, and call the database fluentAPI for consistency with the .env.example file provided. +The database needed for this is MySQL 5.7. The SQL file for this project is located in the `/workbench/database` folder. Please use that to seed your database, and call the database fluentAPI for consistency with the `.env.example` file provided or you can use our migrations. -### Config setup +First create the database `fluentapi` in your MySQL database and get some credentials ready for storage: -Please copy the .env.example file into a new file you can create called .env -You could use the `dotenv populate` command for a wizard to help you make that file. - -Change the host, username and password of the database server you intend to use. - -### Install Dependencies +```bash +# Seed your .env file with your db and credentials +dotenv populate -The box.json stores all of the dependencies of the app, these are not stored in the repo, so please use the command below to install these dependencies ( using ForgeBox behind the scenes ) +# reload the shell so the credentials are loaded +reload -`box install` +# run our migrations +migrate up +``` ### Start the app -Once you have your .env, your db loaded, and your box.json dependencies installed, you can start your server. +Once you have your `.env`, your db loaded, and your `box.json` dependencies installed, you can start your server. `box start` From 93cee914cfc7c202453540355e1b711454828a5a Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 19 May 2020 09:58:27 -0500 Subject: [PATCH 21/75] adding server names and mysql 5.8 compats --- .cfconfig.json | 1 + .env.example | 13 ++++++++++--- server-lucee.json | 5 +++-- server.json | 3 ++- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.cfconfig.json b/.cfconfig.json index 193787f..96a687b 100644 --- a/.cfconfig.json +++ b/.cfconfig.json @@ -1,4 +1,5 @@ { + "adminPassword" : "${ADMIN_PASSWORD}", "requestTimeoutEnabled":true, "whitespaceManagement":"white-space-pref", "requestTimeout":"0,0,5,0", diff --git a/.env.example b/.env.example index 00d4b3b..af2c9ba 100644 --- a/.env.example +++ b/.env.example @@ -3,11 +3,18 @@ APPNAME=fluentAPI ADMIN_PASSWORD=fluentapi ENVIRONMENT=development -# Database Information -DB_CONNECTIONSTRING=jdbc:mysql://127.0.0.1:3306/fluentapi?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true -DB_CLASS=com.mysql.jdbc.Driver +# Lucee DB MySQL 5.8 +#DB_BUNDLENAME=com.mysql.cj # MySQL 8 +#DB_BUNDLEVERSION=8.0.19 # MySQL 8 +#DB_CLASS=com.mysql.cj.jdbc.Driver # MySQL 8 + +# Lucee DB MySQL 5.7 DB_BUNDLENAME=com.mysql.jdbc DB_BUNDLEVERSION=5.1.38 +DB_CLASS=com.mysql.jdbc.Driver + +# Database Information +DB_CONNECTIONSTRING=jdbc:mysql://127.0.0.1:3306/fluentapi?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true DB_DRIVER=MySQL DB_HOST=127.0.0.1 DB_PORT=3306 diff --git a/server-lucee.json b/server-lucee.json index 2dc28f2..b825b29 100644 --- a/server-lucee.json +++ b/server-lucee.json @@ -1,10 +1,11 @@ { + "name":"fluentapi-lucee", "app":{ - "serverHomeDirectory":".engine/lucee5", + "serverHomeDirectory":".engine/lucee5", "cfengine":"lucee@5" }, "web":{ - "directoryBrowsing":true, + "directoryBrowsing":true, "rewrites":{ "enable":true } diff --git a/server.json b/server.json index 61f6825..a25c34f 100644 --- a/server.json +++ b/server.json @@ -8,5 +8,6 @@ "rewrites":{ "enable":true } - } + }, + "name":"fluentapi-adobe" } \ No newline at end of file From 272c1885213e2c373c2984d2a9afa8f4509bfdb9 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 19 May 2020 10:58:42 -0500 Subject: [PATCH 22/75] more fine-tunning --- config/Coldbox.cfc | 2 +- .../api/modules_app/v6/config/Router.cfc | 11 ++++++-- tests/specs/integration/api-v6/RantsTest.cfc | 28 +++++++------------ 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index cee1193..87874d0 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -39,7 +39,7 @@ // Error/Exception Handling invalidHTTPMethodHandler : "", exceptionHandler : "v1:Echo.onError", - invalidEventHandler : "", + invalidEventHandler : "v1:Echo.onInvalidEvent", customErrorTemplate : "", // Application Aspects handlerCaching : true, diff --git a/modules_app/api/modules_app/v6/config/Router.cfc b/modules_app/api/modules_app/v6/config/Router.cfc index adfd4cd..acb589f 100644 --- a/modules_app/api/modules_app/v6/config/Router.cfc +++ b/modules_app/api/modules_app/v6/config/Router.cfc @@ -1,14 +1,19 @@ component { function configure(){ + // Echo + route( "/", "echo.index" ) + + // Type the ID to numeric resources( resource = "rants", parameterName = "rantID-numeric", except = [ "new", "edit" ] - ); + ) + - route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); + // Catch All Invalid Routes + route( "/:anything", "Echo.onInvalidRoute" ) } } diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index c520a9e..98a15ff 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -28,16 +28,14 @@ component extends="tests.resources.BaseTest" { scenario( "Get an individual Rant", function() { given( "I make a get call to /api/v6/rants/:rantID", function() { when( "I pass an invalid rantID", function() { - then( "I will get a 400 error", function() { + then( "it will be ignored and get the full listing", function() { var rantID = "x" var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.error ).toBeFalse(); + expect( event ).toHaveStatusCode( 200 ); + expect( returnedJSON.data ).toBeArray() + expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); } ); @@ -270,16 +268,13 @@ component extends="tests.resources.BaseTest" { } ); when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { + then( "I will get a 405 error because we only accept numeric Ids", function() { var rantID = "abc"; var event = put( "/api/v6/rants/#rantID#", { "userID": "1", "body": "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( event ).toHaveStatusCode( 405 ); + expect( returnedJSON.messages.toString() ).toInclude( "InvalidHTTPMethod" ); } ); } ); @@ -371,12 +366,9 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( event ).toHaveStatusCode( 405 ); + expect( returnedJSON.messages.toString() ).toInclude( "InvalidHTTPMethod" ); } ); } ); From 301094df18e380b96839c650b4e11c69ada3f50f Mon Sep 17 00:00:00 2001 From: jfarraraains <60403511+jfarraraains@users.noreply.github.com> Date: Wed, 27 May 2020 07:59:19 -0500 Subject: [PATCH 23/75] Duplicate expectation removed No need to check the same thing again when it hasn't had an opportunity to change. --- tests/specs/integration/api-v6/RantsTest.cfc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 98a15ff..c56b915 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -15,7 +15,6 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeArray(); @@ -410,4 +409,4 @@ component extends="tests.resources.BaseTest" { } ); } -} \ No newline at end of file +} From 400507daea4f396176e02fbc46c79b5adc21c3a3 Mon Sep 17 00:00:00 2001 From: jfarraraains <60403511+jfarraraains@users.noreply.github.com> Date: Wed, 27 May 2020 08:21:31 -0500 Subject: [PATCH 24/75] Duplicate expect check. Not needed. --- tests/specs/integration/api-v4/RantsTest.cfc | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 64ecc42..0965324 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -15,7 +15,6 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeArray(); From 3541c52e484a09b369a5e985e4d43df11e90c0fd Mon Sep 17 00:00:00 2001 From: jfarraraains <60403511+jfarraraains@users.noreply.github.com> Date: Wed, 27 May 2020 08:25:00 -0500 Subject: [PATCH 25/75] Duplicate Expect Check. Not needed. --- tests/specs/integration/api-v5/RantsTest.cfc | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 22958fd..a85fa86 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -15,7 +15,6 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; //debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeArray(); From 66ffbd2c932c3ff8bbdd805c18987be09be5c391 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:35:46 -0500 Subject: [PATCH 26/75] updated all formatting and linting rules --- .cfformat.json | 28 ++++++----- .cflintrc | 133 +++++++++++++++++++++---------------------------- 2 files changed, 72 insertions(+), 89 deletions(-) diff --git a/.cfformat.json b/.cfformat.json index 1c6ee6d..443ef67 100644 --- a/.cfformat.json +++ b/.cfformat.json @@ -1,13 +1,14 @@ { "array.empty_padding": false, "array.padding": true, - "array.multiline.min_length": 40, + "array.multiline.min_length": 50, "array.multiline.element_count": 2, "array.multiline.leading_comma.padding": true, "array.multiline.leading_comma": false, "alignment.consecutive.assignments": true, "alignment.consecutive.properties": true, "alignment.consecutive.params": true, + "alignment.doc_comments" : true, "brackets.padding": true, "comment.asterisks": "align", "binary_operators.padding": true, @@ -17,22 +18,22 @@ "function_call.multiline.leading_comma.padding": true, "function_call.casing.builtin": "cfdocs", "function_call.casing.userdefined": "camel", - "function_call.multiline.element_count": 2, + "function_call.multiline.element_count": 3, "function_call.multiline.leading_comma": false, - "function_call.multiline.min_length": 40, + "function_call.multiline.min_length": 50, "function_declaration.padding": true, "function_declaration.empty_padding": false, "function_declaration.multiline.leading_comma": false, "function_declaration.multiline.leading_comma.padding": true, - "function_declaration.multiline.element_count": 2, - "function_declaration.multiline.min_length": 40, + "function_declaration.multiline.element_count": 3, + "function_declaration.multiline.min_length": 50, "function_declaration.group_to_block_spacing": "compact", "function_anonymous.empty_padding": false, "function_anonymous.group_to_block_spacing": "compact", - "function_anonymous.multiline.element_count": 2, + "function_anonymous.multiline.element_count": 3, "function_anonymous.multiline.leading_comma": false, "function_anonymous.multiline.leading_comma.padding": true, - "function_anonymous.multiline.min_length": 40, + "function_anonymous.multiline.min_length": 50, "function_anonymous.padding": true, "indent_size": 4, "keywords.block_to_keyword_spacing": "spaced", @@ -41,12 +42,13 @@ "keywords.spacing_to_block": "spaced", "keywords.spacing_to_group": true, "keywords.empty_group_spacing": false, - "max_columns": 120, + "max_columns": 115, "metadata.multiline.element_count": 3, - "metadata.multiline.min_length": 40, + "metadata.multiline.min_length": 50, + "method_call.chain.multiline" : 3, "newline":"\n", "property.multiline.element_count": 3, - "property.multiline.min_length": 40, + "property.multiline.min_length": 30, "parentheses.padding": true, "strings.quote": "double", "strings.attributes.quote": "double", @@ -55,7 +57,7 @@ "struct.empty_padding": false, "struct.multiline.leading_comma": false, "struct.multiline.leading_comma.padding": true, - "struct.multiline.element_count": 1, - "struct.multiline.min_length": 40, + "struct.multiline.element_count": 2, + "struct.multiline.min_length": 60, "tab_indent": true -} \ No newline at end of file +} diff --git a/.cflintrc b/.cflintrc index ab3c3f6..b392d05 100644 --- a/.cflintrc +++ b/.cflintrc @@ -1,81 +1,62 @@ { - "output": [], "rule": [], "includes": [ - { - "code": "AVOID_USING_STRUCTNEW" - }, - { - "code": "AVOID_USING_ARRAYNEW" - }, - { - "code": "AVOID_USING_CFINCLUDE_TAG" - }, - { - "code": "AVOID_USING_CFABORT_TAG" - }, - { - "code": "AVOID_USING_ABORT" - }, - { - "code": "ARG_VAR_CONFLICT" - }, - { - "code": "ARG_VAR_MIXED" - }, - { - "code": "CFQUERYPARAM_REQ" - }, - { - "code": "COMPARE_INSTEAD_OF_ASSIGN" - }, - { - "code": "COMPONENT_HINT_MISSING" - }, - { - "code": "EXCESSIVE_FUNCTION_LENGTH" - }, - { - "code": "EXCESSIVE_COMPONENT_LENGTH" - }, - { - "code": "EXCESSIVE_ARGUMENTS" - }, - { - "code": "EXCESSIVE_FUNCTIONS" - }, - { - "code": "FUNCTION_TOO_COMPLEX" - }, - { - "code": "FUNCTION_HINT_MISSING" - }, - { - "code": "LOCAL_LITERAL_VALUE_USED_TOO_OFTEN" - }, - { - "code": "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN" - }, - { - "code": "MISSING_VAR" - }, - { - "code": "OUTPUT_ATTR" - }, - { - "code": "UNUSED_LOCAL_VARIABLE" - }, - { - "code": "UNUSED_METHOD_ARGUMENT" - }, - { - "code": "SQL_SELECT_STAR" - }, - { - "code": "VAR_ALLCAPS_NAME" - } + { "code": "AVOID_USING_CFINCLUDE_TAG" }, + { "code": "AVOID_USING_CFABORT_TAG" }, + { "code": "AVOID_USING_CFEXECUTE_TAG" }, + { "code": "AVOID_USING_DEBUG_ATTR" }, + { "code": "AVOID_USING_ABORT" }, + { "code": "AVOID_USING_ISDATE" }, + { "code": "AVOID_USING_ISDEBUGMODE" }, + { "code": "AVOID_USING_CFINSERT_TAG" }, + { "code": "AVOID_USING_CFUPDATE_TAG" }, + { "code": "ARG_VAR_CONFLICT" }, + { "code": "ARG_VAR_MIXED" }, + { "code": "ARG_HINT_MISSING" }, + { "code": "ARG_HINT_MISSING_SCRIPT" }, + { "code" : "ARGUMENT_INVALID_NAME" }, + { "code" : "ARGUMENT_ALLCAPS_NAME" }, + { "code" : "ARGUMENT_TOO_WORDY" }, + { "code" : "ARGUMENT_IS_TEMPORARY" }, + { "code": "CFQUERYPARAM_REQ" }, + { "code": "COMPARE_INSTEAD_OF_ASSIGN" }, + { "code": "COMPONENT_HINT_MISSING" }, + { "code" : "COMPONENT_INVALID_NAME" }, + { "code" : "COMPONENT_ALLCAPS_NAME" }, + { "code" : "COMPONENT_TOO_SHORT" }, + { "code" : "COMPONENT_TOO_LONG" }, + { "code" : "COMPONENT_TOO_WORDY" }, + { "code" : "COMPONENT_IS_TEMPORARY" }, + { "code" : "COMPONENT_HAS_PREFIX_OR_POSTFIX" }, + { "code": "COMPLEX_BOOLEAN_CHECK" }, + { "code": "EXCESSIVE_FUNCTION_LENGTH" }, + { "code": "EXCESSIVE_COMPONENT_LENGTH" }, + { "code": "EXCESSIVE_ARGUMENTS" }, + { "code": "EXCESSIVE_FUNCTIONS" }, + { "code": "EXPLICIT_BOOLEAN_CHECK" }, + { "code": "FUNCTION_TOO_COMPLEX" }, + { "code": "FUNCTION_HINT_MISSING" }, + { "code": "FILE_SHOULD_START_WITH_LOWERCASE" }, + { "code": "LOCAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "MISSING_VAR" }, + { "code" : "METHOD_INVALID_NAME" }, + { "code" : "METHOD_ALLCAPS_NAME" }, + { "code" : "METHOD_IS_TEMPORARY" }, + { "code": "NESTED_CFOUTPUT" }, + { "code": "NEVER_USE_QUERY_IN_CFM" }, + { "code": "OUTPUT_ATTR" }, + { "code" : "QUERYPARAM_REQ" }, + { "code": "UNUSED_LOCAL_VARIABLE" }, + { "code": "UNUSED_METHOD_ARGUMENT" }, + { "code": "SQL_SELECT_STAR" }, + { "code": "SCOPE_ALLCAPS_NAME" }, + { "code": "VAR_ALLCAPS_NAME" }, + { "code": "VAR_INVALID_NAME" }, + { "code": "VAR_TOO_WORDY" } ], "inheritParent": false, - "inheritPlugins": true, - "parameters": {} -} \ No newline at end of file + "parameters": { + "TooManyFunctionsChecker.maximum" : 20 + } +} From 7afe94318da22e97226c3ca678a5fea8aad9da47 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:36:04 -0500 Subject: [PATCH 27/75] updated all engine information to latest adobe --- .cfconfig.json | 55 ++++++++++++++++++++--------------------------- server-lucee.json | 10 +++++---- server.json | 16 ++++++++------ 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/.cfconfig.json b/.cfconfig.json index 96a687b..e3784f3 100644 --- a/.cfconfig.json +++ b/.cfconfig.json @@ -1,34 +1,25 @@ { - "adminPassword" : "${ADMIN_PASSWORD}", - "requestTimeoutEnabled":true, - "whitespaceManagement":"white-space-pref", - "requestTimeout":"0,0,5,0", - "cacheDefaultObject":"coldbox", - "caches":{ - "coldbox":{ - "storage":"true", - "type":"RAM", - "custom":{ - "timeToIdleSeconds":"1800", - "timeToLiveSeconds":"3600" - }, - "class":"lucee.runtime.cache.ram.RamCache", - "readOnly":"false" - } - }, - "datasources" : { - "${DB_DATABASE}":{ - "host":"${DB_HOST}", - "dbdriver":"${DB_DRIVER}", - "database":"${DB_DATABASE}", - "dsn":"jdbc:mysql://{host}:{port}/{database}", - "custom":"useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true&autoReconnect=true", - "port":"${DB_PORT}", - "class":"${DB_CLASS}", - "username":"${DB_USER}", - "password":"${DB_PASSWORD}", - "connectionLimit":"100", - "connectionTimeout":"1" - } + "adminPassword": "${CFCONFIG_ADMINPASSWORD}", + "debuggingReportExecutionTimes": false, + "requestTimeoutEnabled": true, + "robustExceptionEnabled": true, + "whitespaceManagement": "white-space-pref", + "requestTimeout": "0,0,5,0", + "datasources": { + "${DB_DATABASE}": { + "bundleName": "${DB_BUNDLENAME}", + "bundleVersion": "${DB_BUNDLEVERSION}", + "class": "${DB_CLASS}", + "custom": "useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true&allowPublicKeyRetrieval=true", + "database": "${DB_DATABASE}", + "dbdriver": "MySQL", + "dsn": "jdbc:mysql://{host}:{port}/{database}", + "host":"${DB_HOST:127.0.0.1}", + "password": "${DB_PASSWORD}", + "port": "${DB_PORT:3306}", + "username": "${DB_USER:root}", + "storage":"false", + "validate":"false" + } } -} \ No newline at end of file +} diff --git a/server-lucee.json b/server-lucee.json index b825b29..e04fee5 100644 --- a/server-lucee.json +++ b/server-lucee.json @@ -1,13 +1,15 @@ { - "name":"fluentapi-lucee", + "name":"fluentapi-lucee", "app":{ "serverHomeDirectory":".engine/lucee5", "cfengine":"lucee@5" }, "web":{ - "directoryBrowsing":true, + "http":{ + "port":"60299" + }, "rewrites":{ - "enable":true + "enable":"true" } } -} \ No newline at end of file +} diff --git a/server.json b/server.json index a25c34f..cdefd1a 100644 --- a/server.json +++ b/server.json @@ -1,13 +1,15 @@ { + "name":"fluentapi-adobe", "app":{ - "serverHomeDirectory":".engine/adobe2018", - "cfengine":"adobe@2018.0.7" + "serverHomeDirectory":".engine/adobe2021", + "cfengine":"adobe@2021" }, "web":{ - "directoryBrowsing":true, + "http":{ + "port":"60299" + }, "rewrites":{ - "enable":true + "enable":"true" } - }, - "name":"fluentapi-adobe" -} \ No newline at end of file + } +} From d2c51a8b0a4fdbd0b26dabfefb83e624e365f550 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:36:14 -0500 Subject: [PATCH 28/75] updated all env vars --- .env.example | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index af2c9ba..ea11e6d 100644 --- a/.env.example +++ b/.env.example @@ -1,32 +1,57 @@ -# ColdBox Environment +################################################################# +# App Name and Environment +################################################################# APPNAME=fluentAPI -ADMIN_PASSWORD=fluentapi +# This can be development, staging, production or custom. ENVIRONMENT=development +# The password for the CFML Engine Administrator +CFCONFIG_ADMINPASSWORD=fluentapi +# The ColdBox Reinit password +COLDBOX_REINITPASSWORD= +# Development CBDebugger +CBDEBUGGER_ENABLED=false -# Lucee DB MySQL 5.8 -#DB_BUNDLENAME=com.mysql.cj # MySQL 8 -#DB_BUNDLEVERSION=8.0.19 # MySQL 8 -#DB_CLASS=com.mysql.cj.jdbc.Driver # MySQL 8 +###################################################### +# MySQL 8+ DB Driver +###################################################### +#DB_BUNDLENAME=com.mysql.cj +#DB_BUNDLEVERSION=8.0.19 +#DB_CLASS=com.mysql.cj.jdbc.Driver -# Lucee DB MySQL 5.7 +###################################################### +# MySQL 5.7 DB Driver +###################################################### DB_BUNDLENAME=com.mysql.jdbc -DB_BUNDLEVERSION=5.1.38 +DB_BUNDLEVERSION=5.1.40 DB_CLASS=com.mysql.jdbc.Driver -# Database Information -DB_CONNECTIONSTRING=jdbc:mysql://127.0.0.1:3306/fluentapi?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true -DB_DRIVER=MySQL +###################################################### +# MySQL * Settings +###################################################### +DB_CONNECTIONSTRING=jdbc:mysql://127.0.0.1:3306/fluentapi?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useLegacyDatetimeCode=true&allowPublicKeyRetrieval=true DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=fluentapi -DB_USER=root +DB_USER= DB_PASSWORD= +################################################################# # JWT Information +# -------------------------------- +# You can seed the JWT secret below or you can also leave it empty +# and ContentBox will auto-generate one for you that rotates +# everytime the application restarts or expires +################################################################# JWT_SECRET= -# S3 Information +################################################################# +# AWS S3 or Digital Ocean Spaces +# -------------------------------- +# If you are using any of our S3/Spaces compatible storages, you +# will have to seed your credentials and information below +################################################################# S3_ACCESS_KEY= S3_SECRET_KEY= S3_REGION=us-east-1 S3_DOMAIN=amazonaws.com +S3_BUCKET= From aa9c509c10a6ede2e0f197c53c336b876d306a18 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:36:21 -0500 Subject: [PATCH 29/75] updated editor files --- .editorconfig | 2 +- .gitignore | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index a2c8081..ec87892 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,4 +17,4 @@ indent_size = 2 [*.{md,markdown}] trim_trailing_whitespace = false -insert_final_newline = false \ No newline at end of file +insert_final_newline = false diff --git a/.gitignore b/.gitignore index 4ffba39..4850a34 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ settings.xml WEB-INF .env .engine/** -.vscode/** # logs + tests logs/** From bfaf8ac17e38f744122d7591503047972ff7e53b Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:36:27 -0500 Subject: [PATCH 30/75] updated all dependencies --- box.json | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/box.json b/box.json index e83ec50..8043f57 100644 --- a/box.json +++ b/box.json @@ -18,20 +18,21 @@ ], "ignore":[], "devDependencies":{ - "relax":"^4.1.0+174", - "route-visualizer":"^1.4.0+24", - "testbox":"^4.0.0", + "relax":"*", + "route-visualizer":"*", + "testbox":"*", "commandbox-dotenv":"*", + "commandbox-docbox":"*", "commandbox-cfconfig":"*", "commandbox-cfformat":"*", "commandbox-migrations":"*" }, "dependencies":{ - "coldbox":"6.0.0-RC", - "cbswagger":"^2.1.1+118", - "cbvalidation":"^2.1.0+126", - "cors":"3.0.2", - "mementifier":"^2.1.0+100" + "coldbox":"^6.7.0+3", + "cbswagger":"^2.6.0+147", + "cbvalidation":"^3.4.0+14", + "cors":"^3.0.6", + "mementifier":"^2.8.0+4" }, "installPaths":{ "coldbox":"coldbox/", @@ -43,18 +44,23 @@ "cors":"modules/cors/", "mementifier":"modules/mementifier/" }, + "testbox":{ + "runner":"http://localhost:60299/tests/runner.cfm" + }, "scripts":{ "start:lucee":"server start serverConfigFile=server-lucee.json --force", "start:adobe":"server start serverConfigFile=server.json --force", + "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", + "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", - "format":"cfformat run modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", - "format:check":"cfformat check modules_app/**/*.cfc,tests/specs/**/*.cfc --verbose", - "test:v1" : "testbox run directory=tests/specs/integration/api-v1", - "test:v2" : "testbox run directory=tests/specs/integration/api-v2", - "test:v3" : "testbox run directory=tests/specs/integration/api-v3", - "test:v4" : "testbox run directory=tests/specs/integration/api-v4", - "test:v5" : "testbox run directory=tests/specs/integration/api-v5", - "test:v6" : "testbox run directory=tests/specs/integration/api-v6" + "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", + "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", + "test:v1":"testbox run directory=tests/specs/integration/api-v1", + "test:v2":"testbox run directory=tests/specs/integration/api-v2", + "test:v3":"testbox run directory=tests/specs/integration/api-v3", + "test:v4":"testbox run directory=tests/specs/integration/api-v4", + "test:v5":"testbox run directory=tests/specs/integration/api-v5", + "test:v6":"testbox run directory=tests/specs/integration/api-v6" }, "cfmigrations":{ "migrationsDirectory":"resources/database/migrations", From 26144ff7ac9e8ae25ca02cb638e51449b7309223 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 14:37:30 -0500 Subject: [PATCH 31/75] updated ports --- box.json | 2 +- readme.md | 4 ++-- server-lucee.json | 2 +- server.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/box.json b/box.json index 8043f57..d3f43d4 100644 --- a/box.json +++ b/box.json @@ -45,7 +45,7 @@ "mementifier":"modules/mementifier/" }, "testbox":{ - "runner":"http://localhost:60299/tests/runner.cfm" + "runner":"http://localhost:60146/tests/runner.cfm" }, "scripts":{ "start:lucee":"server start serverConfigFile=server-lucee.json --force", diff --git a/readme.md b/readme.md index a1efb8f..569b813 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ Just use CommandBox and install them: `box install` ### Database setup -The database needed for this is MySQL 5.7. The SQL file for this project is located in the `/workbench/database` folder. Please use that to seed your database, and call the database fluentAPI for consistency with the `.env.example` file provided or you can use our migrations. +The database needed for this is MySQL 5.7+ or 8+. The SQL file for this project is located in the `/workbench/database` folder. Please use that to seed your database, and call the database fluentAPI for consistency with the `.env.example` file provided or you can use our migrations. First create the database `fluentapi` in your MySQL database and get some credentials ready for storage: @@ -60,4 +60,4 @@ http://127.0.0.1:60146/cbswagger ### View Route Visualizer -http://127.0.0.1:60146/route-visualizer \ No newline at end of file +http://127.0.0.1:60146/route-visualizer diff --git a/server-lucee.json b/server-lucee.json index e04fee5..324a231 100644 --- a/server-lucee.json +++ b/server-lucee.json @@ -6,7 +6,7 @@ }, "web":{ "http":{ - "port":"60299" + "port":"60146" }, "rewrites":{ "enable":"true" diff --git a/server.json b/server.json index cdefd1a..1409540 100644 --- a/server.json +++ b/server.json @@ -6,7 +6,7 @@ }, "web":{ "http":{ - "port":"60299" + "port":"60146" }, "rewrites":{ "enable":"true" From 69c2b53bf6ce5c7c926490d74508e791420ac806 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 15:15:05 -0500 Subject: [PATCH 32/75] prepping for acf 2021 and cbdebugger --- .cfconfig.json | 6 + box.json | 7 +- config/CacheBox.cfc | 38 +++- config/Coldbox.cfc | 183 +++++++++++++++--- config/Router.cfc | 4 +- config/Scheduler.cfc | 75 +++++++ config/WireBox.cfc | 9 +- .../2020_05_15_184033_seedrants.cfc | 2 +- server.json | 2 +- 9 files changed, 286 insertions(+), 40 deletions(-) create mode 100644 config/Scheduler.cfc diff --git a/.cfconfig.json b/.cfconfig.json index e3784f3..7aa099d 100644 --- a/.cfconfig.json +++ b/.cfconfig.json @@ -1,6 +1,12 @@ { + "systemErr":"System", + "systemOut":"System", + "componentCacheEnabled":false, + "thistimezone":"UTC", "adminPassword": "${CFCONFIG_ADMINPASSWORD}", + "debuggingEnabled":true, "debuggingReportExecutionTimes": false, + "disableInternalCFJavaComponents":false, "requestTimeoutEnabled": true, "robustExceptionEnabled": true, "whitespaceManagement": "white-space-pref", diff --git a/box.json b/box.json index d3f43d4..f7aec33 100644 --- a/box.json +++ b/box.json @@ -32,7 +32,8 @@ "cbswagger":"^2.6.0+147", "cbvalidation":"^3.4.0+14", "cors":"^3.0.6", - "mementifier":"^2.8.0+4" + "mementifier":"^2.8.0+4", + "cbdebugger":"^3.4.0+61" }, "installPaths":{ "coldbox":"coldbox/", @@ -42,7 +43,8 @@ "cbvalidation":"modules/cbvalidation/", "route-visualizer":"modules/route-visualizer/", "cors":"modules/cors/", - "mementifier":"modules/mementifier/" + "mementifier":"modules/mementifier/", + "cbdebugger":"modules/cbdebugger/" }, "testbox":{ "runner":"http://localhost:60146/tests/runner.cfm" @@ -52,6 +54,7 @@ "start:adobe":"server start serverConfigFile=server.json --force", "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", + "install:2021":"run-script cfpm:install mysql,debugger", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", diff --git a/config/CacheBox.cfc b/config/CacheBox.cfc index a994fb1..5abc240 100644 --- a/config/CacheBox.cfc +++ b/config/CacheBox.cfc @@ -2,15 +2,21 @@ /** * Configure CacheBox for ColdBox Application Operation */ - function configure(){ - // The CacheBox configuration structure DSL + function configure() { + /** + * -------------------------------------------------------------------------- + * CacheBox Configuration (https://cachebox.ortusbooks.com) + * -------------------------------------------------------------------------- + */ cacheBox = { - // LogBox config already in coldbox app, not needed - // logBoxConfig = "coldbox.system.web.config.LogBox", - - // The defaultCache has an implicit name "default" which is a reserved cache name - // It also has a default provider of cachebox which cannot be changed. - // All timeouts are in minutes + /** + * -------------------------------------------------------------------------- + * Default Cache Configuration + * -------------------------------------------------------------------------- + * The defaultCache has an implicit name "default" which is a reserved cache name + * It also has a default provider of cachebox which cannot be changed. + * All timeouts are in minutes + */ defaultCache : { objectDefaultTimeout : 120, // two hours default objectDefaultLastAccessTimeout : 30, // 30 minutes idle time @@ -23,9 +29,21 @@ objectStore : "ConcurrentStore", // guaranteed objects coldboxEnabled : true }, - // Register all the custom named caches you like here + /** + * -------------------------------------------------------------------------- + * Custom Cache Regions + * -------------------------------------------------------------------------- + * You can use this section to register different cache regions and map them + * to different cache providers + */ caches : { - // Named cache for all coldbox event and view template caching + /** + * -------------------------------------------------------------------------- + * ColdBox Template Cache + * -------------------------------------------------------------------------- + * The ColdBox Template cache region is used for event/view caching and + * other internal facilities that might require a more elastic cache. + */ template : { provider : "coldbox.system.cache.providers.CacheBoxColdBoxProvider", properties : { diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 87874d0..4897423 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -1,5 +1,7 @@ component{ - // Configure ColdBox Application + /** + * Configure the ColdBox App For Production + */ function configure(){ /** * -------------------------------------------------------------------------- @@ -12,10 +14,10 @@ */ coldbox = { // Application Setup - appName : getSystemSetting( "APPNAME", "Your app name here" ), + appName : getSystemSetting( "APPNAME", "Fluent API" ), eventName : "event", // Development Settings - reinitPassword : "", + reinitPassword : getSystemSetting( "COLDBOX_REINITPASSWORD", "" ), reinitKey : "fwreinit", handlersIndexAutoReload : true, // Implicit Events @@ -71,18 +73,6 @@ */ // environments = { development : "localhost,^127\.0\.0\.1" }; - /** - * -------------------------------------------------------------------------- - * Module Loading Directives - * -------------------------------------------------------------------------- - */ - modules = { - // An array of modules names to load, empty means all of them - include : [], - // An array of modules names to NOT load, empty means none - exclude : [] - }; - /** * -------------------------------------------------------------------------- * Application Logging (https://logbox.ortusbooks.com) @@ -92,7 +82,7 @@ */ logBox = { // Define Appenders - appenders : { coldboxTracer : { class : "coldbox.system.logging.appenders.ConsoleAppender" } }, + appenders : { console : { class : "coldbox.system.logging.appenders.ConsoleAppender" } }, // Root Logger root : { levelmax : "INFO", appenders : "*" }, // Implicit Level Categories @@ -135,12 +125,39 @@ * } */ moduleSettings = { + /** + * Mementifier settings: https://forgebox.io/view/mementifier + */ + mementifier : { + // Turn on to use the ISO8601 date/time formatting on all processed date/time properites, else use the masks + iso8601Format : true, + // The default date mask to use for date properties + dateMask : "yyyy-MM-dd", + // The default time mask to use for date properties + timeMask : "HH:mm: ss", + // Enable orm auto default includes: If true and an object doesn't have any `memento` struct defined + // this module will create it with all properties and relationships it can find for the target entity + // leveraging the cborm module. + ormAutoIncludes : true, + // The default value for relationships/getters which return null + nullDefaultValue : "", + // Don't check for getters before invoking them + trustedGetters : false, + // If not empty, convert all date/times to the specific timezone + convertToTimezone : "UTC" + }, + + /** + * -------------------------------------------------------------------------- + * cbSwagger Settings + * -------------------------------------------------------------------------- + */ cbswagger : { // The route prefix to search. Routes beginning with this prefix will be determined to be api routes "routes" : [ "api" ], - // The default output format: json or yml // Any routes to exclude "excludeRoutes" : [], + // The default output format: json or yml "defaultFormat" : "json", // A convention route, relative to your app root, where request/response samples are stored ( e.g. resources/apidocs/responses/[module].[handler].[action].[HTTP Status Code].json ) "samplesPath" : "resources/apidocs", @@ -161,16 +178,23 @@ // A url to the License of your API "license" : { "name" : "Apache 2.0", - "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" + "url" : "https://www.apache.org/licenses/LICENSE-2.0.html" }, // The version of your API "version" : "1.0.0" }, + // Tags + "tags" : [], + // https://swagger.io/specification/#externalDocumentationObject + "externalDocs" : { + "description" : "Find more info here", + "url" : "https://blog.readme.io/an-example-filled-guide-to-swagger-3-2/" + }, // https://swagger.io/specification/#serverObject "servers" : [ { - "url" : "http://127.0.0.1:60146/", - "description" : "Local Development" + "url" : "http://127.0.0.1:60146", + "description" : "Local development" } ], // An element to hold various schemas for the specification. @@ -178,9 +202,32 @@ "components" : { // Define your security schemes here // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject - "securitySchemes" : {} + "securitySchemes" : { + // "ApiKeyAuth" : { + // "type" : "apiKey", + // "description" : "User your JWT as an Api Key for security", + // "name" : "x-api-key", + // "in" : "header" + // }, + // "bearerAuth" : { + // "type" : "http", + // "scheme" : "bearer", + // "bearerFormat" : "JWT" + // } + } } + + // A default declaration of Security Requirement Objects to be used across the API. + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securityRequirementObject + // Only one of these requirements needs to be satisfied to authorize a request. + // Individual operations may set their own requirements with `@security` + // "security" : [ + // { "APIKey" : [] }, + // { "UserSecurity" : [] } + // ] } + + }; } @@ -188,7 +235,99 @@ * Development environment */ function development(){ - // coldbox.customErrorTemplate = "/coldbox/system/exceptions/BugReport.cfm"; + coldbox.handlersIndexAutoReload = true; + coldbox.handlerCaching = false; + coldbox.reinitpassword = ""; coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; + + // Debugger Settings + variables.modulesettings.cbdebugger = { + // This flag enables/disables the tracking of request data to our storage facilities + // To disable all tracking, turn this master key off + enabled : getSystemSetting( "CBDEBUGGER_ENABLED", false ), + // This setting controls if you will activate the debugger for visualizations ONLY + // The debugger will still track requests even in non debug mode. + debugMode : true, + // The URL password to use to activate it on demand + debugPassword : "cb", + // This flag enables/disables the end of request debugger panel docked to the bottom of the page. + // If you disable it, then the only way to visualize the debugger is via the `/cbdebugger` endpoint + requestPanelDock : true, + // Request Tracker Options + requestTracker : { + storage : "cachebox", + cacheName : "template", + trackDebuggerEvents : false, + // Expand by default the tracker panel or not + expanded : false, + // Slow request threshold in milliseconds, if execution time is above it, we mark those transactions as red + slowExecutionThreshold : 1000, + // How many tracking profilers to keep in stack: Default is to monitor the last 20 requests + maxProfilers : 50, + // If enabled, the debugger will monitor the creation time of CFC objects via WireBox + profileWireBoxObjectCreation : false, + // Profile model objects annotated with the `profile` annotation + profileObjects : true, + // If enabled, will trace the results of any methods that are being profiled + traceObjectResults : false, + // Profile Custom or Core interception points + profileInterceptions : false, + // By default all interception events are excluded, you must include what you want to profile + includedInterceptions : [], + // Control the execution timers + executionTimers : { + expanded : true, + // Slow transaction timers in milliseconds, if execution time of the timer is above it, we mark it + slowTimerThreshold : 250 + }, + // Control the coldbox info reporting + coldboxInfo : { expanded : false }, + // Control the http request reporting + httpRequest : { + expanded : false, + // If enabled, we will profile HTTP Body content, disabled by default as it contains lots of data + profileHTTPBody : false + } + }, + // ColdBox Tracer Appender Messages + tracers : { enabled : true, expanded : false }, + // Request Collections Reporting + collections : { + // Enable tracking + enabled : false, + // Expanded panel or not + expanded : false, + // How many rows to dump for object collections + maxQueryRows : 50, + // How many levels to output on dumps for objects + maxDumpTop : 5 + }, + // CacheBox Reporting + cachebox : { enabled : true, expanded : false }, + // Modules Reporting + modules : { enabled : true, expanded : false }, + // Quick and QB Reporting + qb : { + enabled : false, + expanded : false, + // Log the binding parameters + logParams : true + }, + // cborm Reporting + cborm : { + enabled : false, + expanded : false, + // Log the binding parameters + logParams : false + }, + // Adobe ColdFusion SQL Collector + acfSql : { + enabled : true, + expanded : false, + // Log the binding parameters + logParams : true + }, + async : { enabled : true, expanded : false } + }; } } diff --git a/config/Router.cfc b/config/Router.cfc index bfa57f8..7d5a3ee 100644 --- a/config/Router.cfc +++ b/config/Router.cfc @@ -1,6 +1,6 @@ component { - function configure(){ + function configure() { // Set Full Rewrites setFullRewrites( true ); @@ -15,7 +15,7 @@ component { */ // A nice healthcheck route example - route( "/healthcheck", function( event, rc, prc ){ + route( "/healthcheck", function( event, rc, prc ) { return "Ok!"; } ); diff --git a/config/Scheduler.cfc b/config/Scheduler.cfc new file mode 100644 index 0000000..be0de30 --- /dev/null +++ b/config/Scheduler.cfc @@ -0,0 +1,75 @@ +component { + + /** + * Configure the ColdBox Scheduler + */ + function configure() { + /** + * -------------------------------------------------------------------------- + * Configuration Methods + * -------------------------------------------------------------------------- + * From here you can set global configurations for the scheduler + * - setTimezone( ) : change the timezone for ALL tasks + * - setExecutor( executorObject ) : change the executor if needed + */ + + + + /** + * -------------------------------------------------------------------------- + * Register Scheduled Tasks + * -------------------------------------------------------------------------- + * You register tasks with the task() method and get back a ColdBoxScheduledTask object + * that you can use to register your tasks configurations. + */ + + } + + /** + * Called before the scheduler is going to be shutdown + */ + function onShutdown(){ + } + + /** + * Called after the scheduler has registered all schedules + */ + function onStartup(){ + } + + /** + * Called whenever ANY task fails + * + * @task The task that got executed + * @exception The ColdFusion exception object + */ + function onAnyTaskError( required task, required exception ){ + } + + /** + * Called whenever ANY task succeeds + * + * @task The task that got executed + * @result The result (if any) that the task produced + */ + function onAnyTaskSuccess( required task, result ){ + } + + /** + * Called before ANY task runs + * + * @task The task about to be executed + */ + function beforeAnyTask( required task ){ + } + + /** + * Called after ANY task runs + * + * @task The task that got executed + * @result The result (if any) that the task produced + */ + function afterAnyTask( required task, result ){ + } + +} diff --git a/config/WireBox.cfc b/config/WireBox.cfc index 12963f8..4cf9ce4 100644 --- a/config/WireBox.cfc +++ b/config/WireBox.cfc @@ -2,8 +2,13 @@ /** * Configure WireBox, that's it! */ - function configure(){ - // The WireBox configuration structure DSL + function configure() { + /** + * -------------------------------------------------------------------------- + * WireBox Configuration (https://wirebox.ortusbooks.com) + * -------------------------------------------------------------------------- + * Configure WireBox + */ wireBox = { // Scope registration, automatically register a wirebox injector instance on any CF scope // By default it registeres itself on application scope diff --git a/resources/database/migrations/2020_05_15_184033_seedrants.cfc b/resources/database/migrations/2020_05_15_184033_seedrants.cfc index 81a5681..03781a2 100755 --- a/resources/database/migrations/2020_05_15_184033_seedrants.cfc +++ b/resources/database/migrations/2020_05_15_184033_seedrants.cfc @@ -4,7 +4,7 @@ component { queryExecute( " INSERT INTO `users` (`id`, `username`, `email`, `password`, `createdDate`, `modifiedDate`) VALUES (2, 'gpickin', 'gavin@ortussolutions.com', '$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.', '2018-10-04 17:55:19', '2018-10-04 17:55:19'), - (3, 'luis', 'lmajano@ortussolutions.com', '$2a$12$kSM/7Q5WgJ/xaKfLYwbPj.4QVJZo7tonT/h/PFDoUwfW3GDV/AttC', '2018-10-05 09:07:14', '2018-10-05 09:07:14'), + (3, 'luis', 'lmajano@ortussolutions.com', '$2a$12$FE2J7ZLWaI2rSqejAu/84uLy7qlSufQsDsSE1lNNKyA05GG30gr8C', '2018-10-05 09:07:14', '2018-10-05 09:07:14'), (4, 'brad', 'brad@ortussolutions.com', '$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6', '2018-10-05 09:29:37', '2018-10-05 09:29:37'), (5, 'javier', 'jquintero@ortussolutions.com', '$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W', '2018-10-05 09:30:32', '2018-10-05 09:30:32'), (6, 'scott', 'scott@scott.com', '$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.', '2018-10-05 09:32:07', '2018-10-05 09:32:07'), diff --git a/server.json b/server.json index 1409540..30161e5 100644 --- a/server.json +++ b/server.json @@ -1,5 +1,5 @@ { - "name":"fluentapi-adobe", + "name":"fluentapi-adobe", "app":{ "serverHomeDirectory":".engine/adobe2021", "cfengine":"adobe@2021" From 11d09669cc1c7391d4fcb4b1bcac640d35e8636d Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 15:44:58 -0500 Subject: [PATCH 33/75] making sure cbdebugger is working --- .cfconfig.json | 1 + .env.example | 2 +- box.json | 2 +- config/Coldbox.cfc | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.cfconfig.json b/.cfconfig.json index 7aa099d..955609e 100644 --- a/.cfconfig.json +++ b/.cfconfig.json @@ -5,6 +5,7 @@ "thistimezone":"UTC", "adminPassword": "${CFCONFIG_ADMINPASSWORD}", "debuggingEnabled":true, + "debuggingShowDatabase":true, "debuggingReportExecutionTimes": false, "disableInternalCFJavaComponents":false, "requestTimeoutEnabled": true, diff --git a/.env.example b/.env.example index ea11e6d..2bb4c3f 100644 --- a/.env.example +++ b/.env.example @@ -9,7 +9,7 @@ CFCONFIG_ADMINPASSWORD=fluentapi # The ColdBox Reinit password COLDBOX_REINITPASSWORD= # Development CBDebugger -CBDEBUGGER_ENABLED=false +CBDEBUGGER_ENABLED=true ###################################################### # MySQL 8+ DB Driver diff --git a/box.json b/box.json index f7aec33..03e4908 100644 --- a/box.json +++ b/box.json @@ -54,7 +54,7 @@ "start:adobe":"server start serverConfigFile=server.json --force", "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", - "install:2021":"run-script cfpm:install mysql,debugger", + "install:2021":"run-script cfpm:install mysql,debugger,chart", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 4897423..24f1fc7 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -259,7 +259,7 @@ cacheName : "template", trackDebuggerEvents : false, // Expand by default the tracker panel or not - expanded : false, + expanded : true, // Slow request threshold in milliseconds, if execution time is above it, we mark those transactions as red slowExecutionThreshold : 1000, // How many tracking profilers to keep in stack: Default is to monitor the last 20 requests From c9ccac256a02dc1eb360f7416bd6b5c596f5af23 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 12 Jul 2022 15:58:15 -0500 Subject: [PATCH 34/75] remove models, not needed, making it simpler --- models/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 models/.gitkeep diff --git a/models/.gitkeep b/models/.gitkeep deleted file mode 100644 index e69de29..0000000 From fc0d32010fa8f287492a09d4890ca236d3b26987 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 13 Jul 2022 15:56:16 -0500 Subject: [PATCH 35/75] seeding cors --- box.json | 4 ++-- robots.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/box.json b/box.json index 03e4908..afca93c 100644 --- a/box.json +++ b/box.json @@ -31,7 +31,7 @@ "coldbox":"^6.7.0+3", "cbswagger":"^2.6.0+147", "cbvalidation":"^3.4.0+14", - "cors":"^3.0.6", + "cors":"^3.0.0", "mementifier":"^2.8.0+4", "cbdebugger":"^3.4.0+61" }, @@ -54,7 +54,7 @@ "start:adobe":"server start serverConfigFile=server.json --force", "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", - "install:2021":"run-script cfpm:install mysql,debugger,chart", + "install:2021":"run-script cfpm:install mysql,debugger,chart", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", diff --git a/robots.txt b/robots.txt index 7cf7e88..dfd0764 100644 --- a/robots.txt +++ b/robots.txt @@ -3,7 +3,7 @@ User-agent: Slurp Crawl-delay: 100 Disallow: -User-agent: gsa-crawler-www +User-agent: gsa-crawler-www Crawl-delay: 100 User-agent: Googlebot @@ -30,4 +30,4 @@ Disallow: /models/ Disallow: /modules/ Disallow: /modules_app/ Disallow: /views/ -Allow: / \ No newline at end of file +Allow: / From 86d1be9deddf2988089946d5c06a1f29fe112287 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 13 Jul 2022 16:47:24 -0500 Subject: [PATCH 36/75] updated migrations to use the schema builder and mocked data. --- .../2020_05_15_183916_buildrants.cfc | 37 ------- .../migrations/2020_05_15_183916_users.cfc | 18 ++++ .../migrations/2020_05_15_183939_rants.cfc | 18 ++++ .../2020_05_15_184033_seedrants.cfc | 102 ++++++++++++------ 4 files changed, 104 insertions(+), 71 deletions(-) delete mode 100755 resources/database/migrations/2020_05_15_183916_buildrants.cfc create mode 100755 resources/database/migrations/2020_05_15_183916_users.cfc create mode 100755 resources/database/migrations/2020_05_15_183939_rants.cfc diff --git a/resources/database/migrations/2020_05_15_183916_buildrants.cfc b/resources/database/migrations/2020_05_15_183916_buildrants.cfc deleted file mode 100755 index d8aa8f7..0000000 --- a/resources/database/migrations/2020_05_15_183916_buildrants.cfc +++ /dev/null @@ -1,37 +0,0 @@ -component { - - function up( schema, query ) { - queryExecute( " - CREATE TABLE IF NOT EXISTS `users` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `username` varchar(255) NOT NULL, - `email` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `username` (`username`), - UNIQUE KEY `email` (`email`) - ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4; - " ); - - queryExecute( " - CREATE TABLE IF NOT EXISTS `rants` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `body` text NOT NULL, - `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `userId` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `fk_rants_userId` (`userId`), - CONSTRAINT `fk_rants_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE - ) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4; - " ); - } - - function down( schema, query ) { - schema.drop( "rants" ); - schema.drop( "users" ); - } - -} diff --git a/resources/database/migrations/2020_05_15_183916_users.cfc b/resources/database/migrations/2020_05_15_183916_users.cfc new file mode 100755 index 0000000..ec65186 --- /dev/null +++ b/resources/database/migrations/2020_05_15_183916_users.cfc @@ -0,0 +1,18 @@ +component { + + function up( schema, query ) { + schema.create( "users", ( table ) => { + table.string( "id" ).primaryKey(); + table.string( "username" ).unique(); + table.string( "email" ).unique(); + table.string( "password" ); + table.datetime( "createdDate" ).withCurrent(); + table.datetime( "updatedDate" ).withCurrent(); + } ); + } + + function down( schema, query ) { + schema.drop( "users" ); + } + +} diff --git a/resources/database/migrations/2020_05_15_183939_rants.cfc b/resources/database/migrations/2020_05_15_183939_rants.cfc new file mode 100755 index 0000000..897809e --- /dev/null +++ b/resources/database/migrations/2020_05_15_183939_rants.cfc @@ -0,0 +1,18 @@ +component { + + function up( schema, query ) { + schema.create( "rants", ( table ) => { + table.string( "id" ).primaryKey() + table.text( "body" ) + table.datetime( "createdDate" ).withCurrent() + table.datetime( "updatedDate" ).withCurrent() + table.string( "userId" ); + table.foreignKey( "userId" ).references( "id" ).onTable( "users" ); + } ); + } + + function down( schema, query ) { + schema.drop( "rants" ); + } + +} diff --git a/resources/database/migrations/2020_05_15_184033_seedrants.cfc b/resources/database/migrations/2020_05_15_184033_seedrants.cfc index 03781a2..5f93b5d 100755 --- a/resources/database/migrations/2020_05_15_184033_seedrants.cfc +++ b/resources/database/migrations/2020_05_15_184033_seedrants.cfc @@ -1,41 +1,75 @@ component { + messages = [ + 'Another rant', + "This is the most amazing post in my life", + "I love kittens", + "I love espresso", + "I love soccer!", + "Why is this here!", + "Captain America is the best superhero!", + 'Testing test test', + 'Scott likes me preso', + 'Scott seems to like my preso', + 'What are you talking about!', + "This post is not really good, it sucked!", + "Why are you doing this to me!", + "Please please please delete!" + ]; + + users = [ + { + id : '#createUUID()#' , + username : 'gpickin', + email : 'gavin@ortussolutions.com', + password : '$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.' + }, + { + id : '#createUUID()#' , + username : 'luis', + email : 'lmajano@ortussolutions.com', + password : '$2a$12$FE2J7ZLWaI2rSqejAu/84uLy7qlSufQsDsSE1lNNKyA05GG30gr8C' + }, + { + id : '#createUUID()#' , + username : 'brad', + email : 'brad@ortussolutions.com', + password : '$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6' + }, + { + id : '#createUUID()#' , + username : 'javier', + email : 'jquintero@ortussolutions.com', + password : '$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W' + }, + { + id : '#createUUID()#' , + username : 'scott', + email : 'scott@scott.com', + password : '$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.' + }, + { + id : '#createUUID()#' , + username : 'mike', + email : 'mikep@netxn.com', + password : '$2a$12$WWUwFEAoDGx.vB0jE54xser1myMUSwUMYo/aNn0cSGa8l6DQe67Q2' + } + ]; + function up( schema, query ) { - queryExecute( " - INSERT INTO `users` (`id`, `username`, `email`, `password`, `createdDate`, `modifiedDate`) VALUES - (2, 'gpickin', 'gavin@ortussolutions.com', '$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.', '2018-10-04 17:55:19', '2018-10-04 17:55:19'), - (3, 'luis', 'lmajano@ortussolutions.com', '$2a$12$FE2J7ZLWaI2rSqejAu/84uLy7qlSufQsDsSE1lNNKyA05GG30gr8C', '2018-10-05 09:07:14', '2018-10-05 09:07:14'), - (4, 'brad', 'brad@ortussolutions.com', '$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6', '2018-10-05 09:29:37', '2018-10-05 09:29:37'), - (5, 'javier', 'jquintero@ortussolutions.com', '$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W', '2018-10-05 09:30:32', '2018-10-05 09:30:32'), - (6, 'scott', 'scott@scott.com', '$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.', '2018-10-05 09:32:07', '2018-10-05 09:32:07'), - (7, 'mike', 'mikep@netxn.com', '$2a$12$WWUwFEAoDGx.vB0jE54xser1myMUSwUMYo/aNn0cSGa8l6DQe67Q2', '2018-10-05 09:33:00', '2018-10-05 09:33:00'); - " ); + // insert users + query.newQuery().from( "users" ).insert( users ); - queryExecute( " - INSERT INTO `rants` (`id`, `body`, `createdDate`, `modifiedDate`, `userId`) VALUES - (4, 'Another rant', '2020-05-03 23:00:07', '2020-05-03 23:00:07', 2), - (6, 'Another rant, where\'s my soapbox2', '2020-05-03 23:07:39', '2020-05-04 11:22:48', 3), - (7, 'Another rant, where\'s my soapbox23', '2020-05-03 23:20:22', '2020-05-07 11:43:07', 2), - (8, 'Another rant, where\'s my soapbox2', '2020-05-04 11:21:31', '2020-05-04 11:21:31', 2), - (9, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:18', '2020-05-04 12:05:18', 2), - (10, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:44', '2020-05-04 12:05:44', 2), - (11, 'Another rant, where\'s my soapbox2', '2020-05-04 20:58:28', '2020-05-04 20:58:28', 2), - (12, 'Another rant, where\'s my soapbox2', '2020-05-04 20:59:44', '2020-05-04 20:59:44', 2), - (13, 'Another rant, where\'s my soapbox2', '2020-05-04 21:06:16', '2020-05-04 21:06:16', 2), - (14, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:03', '2020-05-04 21:09:03', 2), - (15, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:13', '2020-05-04 21:09:13', 2), - (16, 'Another rant, where\'s my soapbox2', '2020-05-04 21:15:10', '2020-05-04 21:15:10', 2), - (18, 'Another rant, where\'s my soapbox2', '2020-05-07 09:29:06', '2020-05-07 09:29:06', 2), - (19, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:38', '2020-05-07 09:30:38', 2), - (20, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:46', '2020-05-07 09:30:46', 2), - (23, 'Another rant, where\'s my soapbox2', '2020-05-07 09:36:04', '2020-05-07 09:36:04', 2), - (24, 'Another rant, where\'s my soapbox2', '2020-05-07 09:37:03', '2020-05-07 09:37:03', 2), - (25, 'Another rant, where\'s my soapbox2', '2020-05-07 09:46:15', '2020-05-07 09:46:15', 2), - (110, 'Testing test test', '2020-05-07 22:18:43', '2020-05-07 22:18:43', 2), - (111, 'Testing test test', '2020-05-07 22:19:31', '2020-05-07 22:19:31', 2), - (112, 'Scott likes me preso', '2020-05-07 22:19:37', '2020-05-07 22:19:37', 5), - (113, 'Scott seems to like my preso', '2020-05-07 22:20:32', '2020-05-07 22:20:32', 2); - " ); + // insert random rants + var rants = []; + for( var x = 1; x lte 20; x++ ){ + rants.append( { + "id" : createUUID(), + "body" : messages[ randRange( 1, messages.len() ) ], + "userId" : users[ randRange( 1, users.len() ) ].id + } ); + } + query.newQuery().from( "rants" ).insert( rants ); } function down( schema, query ) { From 21202498211eccd20bc733bc56014c77695a0e78 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 13 Jul 2022 18:41:45 -0500 Subject: [PATCH 37/75] new db based on uuid --- workbench/database/20200507_fluentapi.sql | 167 ++++++++++++++-------- 1 file changed, 110 insertions(+), 57 deletions(-) diff --git a/workbench/database/20200507_fluentapi.sql b/workbench/database/20200507_fluentapi.sql index 1d637e9..cd7ee48 100644 --- a/workbench/database/20200507_fluentapi.sql +++ b/workbench/database/20200507_fluentapi.sql @@ -1,79 +1,132 @@ --- -------------------------------------------------------- --- Host: 127.0.0.1 --- Server version: 5.7.12 - MySQL Community Server (GPL) --- Server OS: Win64 --- HeidiSQL Version: 11.0.0.5919 --- -------------------------------------------------------- +# ************************************************************ +# Sequel Ace SQL dump +# Version 20033 +# +# https://sequel-ace.com/ +# https://github.com/Sequel-Ace/Sequel-Ace +# +# Host: 127.0.0.1 (MySQL 5.7.22) +# Database: fluentapi +# Generation Time: 2022-07-13 23:41:21 +0000 +# ************************************************************ + /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET NAMES utf8 */; -/*!50503 SET NAMES utf8mb4 */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +SET NAMES utf8mb4; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40101 SET @OLD_SQL_MODE='NO_AUTO_VALUE_ON_ZERO', SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + + +# Dump of table cfmigrations +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `cfmigrations`; + +CREATE TABLE `cfmigrations` ( + `name` varchar(190) NOT NULL, + `migration_ran` datetime NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +LOCK TABLES `cfmigrations` WRITE; +/*!40000 ALTER TABLE `cfmigrations` DISABLE KEYS */; + +INSERT INTO `cfmigrations` (`name`, `migration_ran`) +VALUES + ('2020_05_15_183916_users','2022-07-13 16:46:50'), + ('2020_05_15_183939_rants','2022-07-13 16:46:50'), + ('2020_05_15_184033_seedrants','2022-07-13 16:46:50'); + +/*!40000 ALTER TABLE `cfmigrations` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table rants +# ------------------------------------------------------------ --- Dumping structure for table fluentapi.rants -CREATE TABLE IF NOT EXISTS `rants` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +DROP TABLE IF EXISTS `rants`; + +CREATE TABLE `rants` ( + `id` varchar(255) NOT NULL, `body` text NOT NULL, - `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `userId` int(10) unsigned NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updatedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `userId` varchar(255) NOT NULL, PRIMARY KEY (`id`), KEY `fk_rants_userId` (`userId`), - CONSTRAINT `fk_rants_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4; + CONSTRAINT `fk_rants_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; --- Dumping data for table fluentapi.rants: ~23 rows (approximately) +LOCK TABLES `rants` WRITE; /*!40000 ALTER TABLE `rants` DISABLE KEYS */; -INSERT INTO `rants` (`id`, `body`, `createdDate`, `modifiedDate`, `userId`) VALUES - (4, 'Another rant', '2020-05-03 23:00:07', '2020-05-03 23:00:07', 2), - (6, 'Another rant, where\'s my soapbox2', '2020-05-03 23:07:39', '2020-05-04 11:22:48', 3), - (7, 'Another rant, where\'s my soapbox23', '2020-05-03 23:20:22', '2020-05-07 11:43:07', 2), - (8, 'Another rant, where\'s my soapbox2', '2020-05-04 11:21:31', '2020-05-04 11:21:31', 2), - (9, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:18', '2020-05-04 12:05:18', 2), - (10, 'Another rant, where\'s my soapbox2', '2020-05-04 12:05:44', '2020-05-04 12:05:44', 2), - (11, 'Another rant, where\'s my soapbox2', '2020-05-04 20:58:28', '2020-05-04 20:58:28', 2), - (12, 'Another rant, where\'s my soapbox2', '2020-05-04 20:59:44', '2020-05-04 20:59:44', 2), - (13, 'Another rant, where\'s my soapbox2', '2020-05-04 21:06:16', '2020-05-04 21:06:16', 2), - (14, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:03', '2020-05-04 21:09:03', 2), - (15, 'Another rant, where\'s my soapbox2', '2020-05-04 21:09:13', '2020-05-04 21:09:13', 2), - (16, 'Another rant, where\'s my soapbox2', '2020-05-04 21:15:10', '2020-05-04 21:15:10', 2), - (18, 'Another rant, where\'s my soapbox2', '2020-05-07 09:29:06', '2020-05-07 09:29:06', 2), - (19, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:38', '2020-05-07 09:30:38', 2), - (20, 'Another rant, where\'s my soapbox2', '2020-05-07 09:30:46', '2020-05-07 09:30:46', 2), - (23, 'Another rant, where\'s my soapbox2', '2020-05-07 09:36:04', '2020-05-07 09:36:04', 2), - (24, 'Another rant, where\'s my soapbox2', '2020-05-07 09:37:03', '2020-05-07 09:37:03', 2), - (25, 'Another rant, where\'s my soapbox2', '2020-05-07 09:46:15', '2020-05-07 09:46:15', 2), - (110, 'Testing test test', '2020-05-07 22:18:43', '2020-05-07 22:18:43', 2), - (111, 'Testing test test', '2020-05-07 22:19:31', '2020-05-07 22:19:31', 2), - (112, 'Scott likes me preso', '2020-05-07 22:19:37', '2020-05-07 22:19:37', 5), - (113, 'Scott seems to like my preso', '2020-05-07 22:20:32', '2020-05-07 22:20:32', 2); + +INSERT INTO `rants` (`id`, `body`, `createdDate`, `updatedDate`, `userId`) +VALUES + ('0B068E2D-1E29-4049-BC5DDABE1491C25C','Captain America is the best superhero!','2022-07-13 16:46:49','2022-07-13 16:46:49','753C0511-257A-4674-92A7500293D60B28'), + ('106EEAB6-44CA-43C2-AF85FA0CAAB86311','Testing test test','2022-07-13 16:46:49','2022-07-13 16:46:49','98BA3147-4071-4301-A011B1BD746077A3'), + ('1E9B6514-13DC-44E5-8DA61A5CE3593041','This is the most amazing post in my life','2022-07-13 16:46:49','2022-07-13 16:46:49','E2F8B589-19E2-46DB-BE64D52483E6F6C6'), + ('1FCCEC67-FB0E-4EE4-97C11403B1F890B3','I love kittens','2022-07-13 16:46:49','2022-07-13 16:46:49','147EB3B9-9102-4910-869CD8529F642AEE'), + ('21626EB7-0AC7-4577-A6A10F929E916C79','What are you talking about!','2022-07-13 16:46:49','2022-07-13 16:46:49','147EB3B9-9102-4910-869CD8529F642AEE'), + ('345AEC61-C741-4338-AF24BE1743C4F640','Scott seems to like my preso','2022-07-13 16:46:49','2022-07-13 16:46:49','98BA3147-4071-4301-A011B1BD746077A3'), + ('381E5F38-7E87-4D3D-A7EA6BBC3C53D44C','I love soccer!','2022-07-13 16:46:49','2022-07-13 16:46:49','753C0511-257A-4674-92A7500293D60B28'), + ('4D442EF9-B36B-4E3F-A2844FA2B77A3F76','This is the most amazing post in my life','2022-07-13 16:46:49','2022-07-13 16:46:49','9B232F88-8745-4872-A7D032BDA6AEE710'), + ('576E42A0-98BA-4721-A4B3C6E8DC078455','Testing test test','2022-07-13 16:46:49','2022-07-13 16:46:49','9B232F88-8745-4872-A7D032BDA6AEE710'), + ('6603FC86-279F-43AF-92C0DFABCD7BCD2B','Scott likes me preso','2022-07-13 16:46:49','2022-07-13 16:46:49','21B8DE1B-DE0D-456E-A56AF767AC72ADBF'), + ('6E6D7AE4-E35B-4656-80D41B9F0A690561','Another rant','2022-07-13 16:46:49','2022-07-13 16:46:49','98BA3147-4071-4301-A011B1BD746077A3'), + ('7A62D3C0-56EB-495F-8F401A5925E5E5A8','Why is this here!','2022-07-13 16:46:49','2022-07-13 16:46:49','753C0511-257A-4674-92A7500293D60B28'), + ('81D28072-B557-4CD7-BDA6A728F40CD020','This post is not really good, it sucked!','2022-07-13 16:46:49','2022-07-13 16:46:49','21B8DE1B-DE0D-456E-A56AF767AC72ADBF'), + ('9E88A5E4-D1E9-4314-A67D08C30E2CEFEC','Why are you doing this to me!','2022-07-13 16:46:49','2022-07-13 16:46:49','E2F8B589-19E2-46DB-BE64D52483E6F6C6'), + ('A1AC85E5-8D2A-4751-B985100FA55A1495','I love espresso','2022-07-13 16:46:49','2022-07-13 16:46:49','98BA3147-4071-4301-A011B1BD746077A3'), + ('B295B834-970D-4A88-B2C21DB1CE3C94EE','Please please please delete!','2022-07-13 16:46:49','2022-07-13 16:46:49','E2F8B589-19E2-46DB-BE64D52483E6F6C6'), + ('D2EF83D6-1AE3-49D6-BCAA74422C8E2661','Scott seems to like my preso','2022-07-13 16:46:49','2022-07-13 16:46:49','147EB3B9-9102-4910-869CD8529F642AEE'), + ('D967F1DA-9EB3-406F-A775D02203B46911','Captain America is the best superhero!','2022-07-13 16:46:49','2022-07-13 16:46:49','147EB3B9-9102-4910-869CD8529F642AEE'), + ('E404B499-6C91-4512-9F8D34E6199016A8','I love espresso','2022-07-13 16:46:49','2022-07-13 16:46:49','753C0511-257A-4674-92A7500293D60B28'), + ('F7A3E616-574E-4177-BB3E9E980218C125','Scott likes me preso','2022-07-13 16:46:49','2022-07-13 16:46:49','147EB3B9-9102-4910-869CD8529F642AEE'); + /*!40000 ALTER TABLE `rants` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table users +# ------------------------------------------------------------ --- Dumping structure for table fluentapi.users -CREATE TABLE IF NOT EXISTS `users` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +DROP TABLE IF EXISTS `users`; + +CREATE TABLE `users` ( + `id` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, - `createdDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modifiedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updatedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`) -) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; --- Dumping data for table fluentapi.users: ~6 rows (approximately) +LOCK TABLES `users` WRITE; /*!40000 ALTER TABLE `users` DISABLE KEYS */; -INSERT INTO `users` (`id`, `username`, `email`, `password`, `createdDate`, `modifiedDate`) VALUES - (2, 'gpickin', 'gavin@ortussolutions.com', '$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.', '2018-10-04 17:55:19', '2018-10-04 17:55:19'), - (3, 'luis', 'lmajano@ortussolutions.com', '$2a$12$kSM/7Q5WgJ/xaKfLYwbPj.4QVJZo7tonT/h/PFDoUwfW3GDV/AttC', '2018-10-05 09:07:14', '2018-10-05 09:07:14'), - (4, 'brad', 'brad@ortussolutions.com', '$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6', '2018-10-05 09:29:37', '2018-10-05 09:29:37'), - (5, 'javier', 'jquintero@ortussolutions.com', '$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W', '2018-10-05 09:30:32', '2018-10-05 09:30:32'), - (6, 'scott', 'scott@scott.com', '$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.', '2018-10-05 09:32:07', '2018-10-05 09:32:07'), - (7, 'mike', 'mikep@netxn.com', '$2a$12$WWUwFEAoDGx.vB0jE54xser1myMUSwUMYo/aNn0cSGa8l6DQe67Q2', '2018-10-05 09:33:00', '2018-10-05 09:33:00'); + +INSERT INTO `users` (`id`, `username`, `email`, `password`, `createdDate`, `updatedDate`) +VALUES + ('147EB3B9-9102-4910-869CD8529F642AEE','luis','lmajano@ortussolutions.com','$2a$12$FE2J7ZLWaI2rSqejAu/84uLy7qlSufQsDsSE1lNNKyA05GG30gr8C','2022-07-13 16:46:49','2022-07-13 16:46:49'), + ('21B8DE1B-DE0D-456E-A56AF767AC72ADBF','brad','brad@ortussolutions.com','$2a$12$Vbb4dYywI5X.1qKEV2mDzeOTZk3iHIDfEtz80SoMT0KkFWTkb.PB6','2022-07-13 16:46:49','2022-07-13 16:46:49'), + ('753C0511-257A-4674-92A7500293D60B28','mike','mikep@netxn.com','$2a$12$WWUwFEAoDGx.vB0jE54xser1myMUSwUMYo/aNn0cSGa8l6DQe67Q2','2022-07-13 16:46:49','2022-07-13 16:46:49'), + ('98BA3147-4071-4301-A011B1BD746077A3','gpickin','gavin@ortussolutions.com','$2a$12$JKiBJZF352Tfm/c3PpeslOBKRAwtXlwczMPKeUV1raD0d1cwh5B5.','2022-07-13 16:46:49','2022-07-13 16:46:49'), + ('9B232F88-8745-4872-A7D032BDA6AEE710','scott','scott@scott.com','$2a$12$OjIpxecG9AlZTgVGV1jsvOegTwbqgJ29PlUkfomGsK/6hsVicsRW.','2022-07-13 16:46:49','2022-07-13 16:46:49'), + ('E2F8B589-19E2-46DB-BE64D52483E6F6C6','javier','jquintero@ortussolutions.com','$2a$12$UIEOglSflvGUbn5sHeBZ1.sAlaoBI4rpNOCIk2vF8R2KKz.ihP9/W','2022-07-13 16:46:49','2022-07-13 16:46:49'); + /*!40000 ALTER TABLE `users` ENABLE KEYS */; +UNLOCK TABLES; + + -/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; -/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; From efb640aac19618b3233e3514cb3c3cdf269adc16 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 14 Jul 2022 09:26:26 -0500 Subject: [PATCH 38/75] wip --- config/Coldbox.cfc | 4 ++-- modules_app/api/ModuleConfig.cfc | 5 +++-- modules_app/api/modules_app/v1/ModuleConfig.cfc | 4 ++-- modules_app/api/modules_app/v1/config/Router.cfc | 1 - modules_app/api/modules_app/v1/handlers/Echo.cfc | 6 +++--- modules_app/api/modules_app/v1/handlers/Rants.cfc | 1 - 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 24f1fc7..63cd536 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -41,7 +41,7 @@ // Error/Exception Handling invalidHTTPMethodHandler : "", exceptionHandler : "v1:Echo.onError", - invalidEventHandler : "v1:Echo.onInvalidEvent", + invalidEventHandler : "v1:Echo.onInvalidRoute", customErrorTemplate : "", // Application Aspects handlerCaching : true, @@ -244,7 +244,7 @@ variables.modulesettings.cbdebugger = { // This flag enables/disables the tracking of request data to our storage facilities // To disable all tracking, turn this master key off - enabled : getSystemSetting( "CBDEBUGGER_ENABLED", false ), + enabled : true,//getSystemSetting( "CBDEBUGGER_ENABLED", false ), // This setting controls if you will activate the debugger for visualizations ONLY // The debugger will still track requests even in non debug mode. debugMode : true, diff --git a/modules_app/api/ModuleConfig.cfc b/modules_app/api/ModuleConfig.cfc index 5547df2..813a59c 100644 --- a/modules_app/api/ModuleConfig.cfc +++ b/modules_app/api/ModuleConfig.cfc @@ -1,5 +1,5 @@ /** - * Module Config + * API Core Module Configuration */ component { @@ -7,7 +7,8 @@ component { this.title = "api"; this.description = "Base API Module"; this.version = "1.0.0"; - // Module Entry Point + + // Module Entry Point in the URI: http://yourapp/api this.entryPoint = "api"; // Inheritable entry point. this.inheritEntryPoint = true; diff --git a/modules_app/api/modules_app/v1/ModuleConfig.cfc b/modules_app/api/modules_app/v1/ModuleConfig.cfc index 9232950..f29697b 100644 --- a/modules_app/api/modules_app/v1/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v1/ModuleConfig.cfc @@ -1,5 +1,5 @@ /** - * Module Config + * v1 Module Config */ component { @@ -7,7 +7,7 @@ component { this.title = "v1"; // Module Entry Point this.entryPoint = "v1"; - // Inherit entry point from parent, so this will be /api/v1 + // Inherit URI entry point from parent, so this will be /api/v1 this.inheritEntryPoint = true; // Model Namespace this.modelNamespace = "v1"; diff --git a/modules_app/api/modules_app/v1/config/Router.cfc b/modules_app/api/modules_app/v1/config/Router.cfc index 4cc65e3..b84a840 100644 --- a/modules_app/api/modules_app/v1/config/Router.cfc +++ b/modules_app/api/modules_app/v1/config/Router.cfc @@ -2,7 +2,6 @@ component { function configure(){ route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); } } diff --git a/modules_app/api/modules_app/v1/handlers/Echo.cfc b/modules_app/api/modules_app/v1/handlers/Echo.cfc index 688a4c4..0b55892 100644 --- a/modules_app/api/modules_app/v1/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v1/handlers/Echo.cfc @@ -15,10 +15,10 @@ component extends="coldbox.system.RestHandler" { this.allowedMethods = {}; /** - * Index + * Say Hello */ - any function index( event, rc, prc ){ - event.getResponse().setData( "Welcome to my ColdBox RESTFul Service V1" ); + function index( event, rc, prc ){ + event.getResponse().setData( "Welcome to my ColdBox RESTFul Service v1" ); } } diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index 28e9a9e..df15e27 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -7,7 +7,6 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v1"; property name="userService" inject="UserService@v1"; - /** * Returns a list of Rants */ From 12847aee5733285913551c401db07e0f541cf9b8 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 14 Jul 2022 15:32:52 -0500 Subject: [PATCH 39/75] v1 now working --- .vscode/settings.json | 14 + .../api/modules_app/v1/config/Router.cfc | 2 + .../api/modules_app/v1/handlers/Echo.cfc | 2 +- .../api/modules_app/v1/handlers/Rants.cfc | 29 +- .../api/modules_app/v1/models/RantService.cfc | 81 ++--- .../api/modules_app/v1/models/UserService.cfc | 9 +- tests/specs/integration/api-v1/EchoTests.cfc | 45 +-- tests/specs/integration/api-v1/RantsTest.cfc | 328 +++++++++--------- 8 files changed, 257 insertions(+), 253 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f20eddc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "cfml.mappings": [ + { + "logicalPath": "/coldbox", + "directoryPath": "./coldbox", + "isPhysicalDirectoryPath" :false + }, + { + "logicalPath": "/testbox", + "directoryPath": "./testbox", + "isPhysicalDirectoryPath" :false + } + ] +} diff --git a/modules_app/api/modules_app/v1/config/Router.cfc b/modules_app/api/modules_app/v1/config/Router.cfc index b84a840..eb9617a 100644 --- a/modules_app/api/modules_app/v1/config/Router.cfc +++ b/modules_app/api/modules_app/v1/config/Router.cfc @@ -1,7 +1,9 @@ component { function configure(){ + // Version Entry Point route( "/", "echo.index" ); + // No more routing as we are using convention based routing thanks to ColdBox } } diff --git a/modules_app/api/modules_app/v1/handlers/Echo.cfc b/modules_app/api/modules_app/v1/handlers/Echo.cfc index 0b55892..f6d5be7 100644 --- a/modules_app/api/modules_app/v1/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v1/handlers/Echo.cfc @@ -15,7 +15,7 @@ component extends="coldbox.system.RestHandler" { this.allowedMethods = {}; /** - * Say Hello + * Say Hello v1 */ function index( event, rc, prc ){ event.getResponse().setData( "Welcome to my ColdBox RESTFul Service v1" ); diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index df15e27..69d351d 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -17,7 +22,6 @@ component extends="coldbox.system.RestHandler" { /** * Returns a single Rant - * */ function view( event, rc, prc ){ if ( !structKeyExists( rc, "rantID" ) ) { @@ -26,10 +30,10 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "rantID is required" ); return; } - if ( !isNumeric( rc.rantID ) ) { + if ( !isValid( "uuid", rc.rantID ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be numeric" ); + prc.response.addMessage( "rantID must be a UUID" ); return; } var rant = rantService.getRant( rc.rantID ); @@ -45,17 +49,16 @@ component extends="coldbox.system.RestHandler" { /** * Deletes a single Rant - * */ function delete( event, rc, prc ){ if ( !structKeyExists( rc, "rantID" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); prc.response.addMessage( "rantID is required" ); - } else if ( !isNumeric( rc.rantID ) ) { + } else if ( !isValid( "UUID", rc.rantID ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be numeric" ); + prc.response.addMessage( "rantID must be a UUID" ); } else { var result = rantService.delete( rc.rantID ); if ( result.recordcount > 0 ) { @@ -70,7 +73,6 @@ component extends="coldbox.system.RestHandler" { /** * Creates a new Rant - * */ function create( event, rc, prc ){ if ( !structKeyExists( rc, "body" ) ) { @@ -91,10 +93,10 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "userID is required" ); return; } - if ( !isNumeric( rc.userID ) ) { + if ( !isValid( "uuid", rc.userID ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID must be numeric" ); + prc.response.addMessage( "userID must be a UUID" ); return; } var user = userService.get( rc.userID ) @@ -119,7 +121,6 @@ component extends="coldbox.system.RestHandler" { /** * Updates an Existing Rant - * */ function save( event, rc, prc ){ if ( !structKeyExists( rc, "body" ) ) { @@ -140,10 +141,10 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "rantID is required" ); return } - if ( !isNumeric( rc.rantID ) ) { + if ( !isValid( "uuid", rc.rantID ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be numeric" ); + prc.response.addMessage( "rantID must be a UUID" ); return } var rant = rantService.getRant( rc.rantID ) @@ -159,10 +160,10 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "userID is required" ); return; } - if ( !isNumeric( rc.userID ) ) { + if ( !isValid( "UUID", rc.userID ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID must be numeric" ); + prc.response.addMessage( "userID must be a UUID" ); return; } var user = userService.get( rc.userID ) diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index 944b58c..172ca5f 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -14,89 +14,58 @@ component singleton accessors="true" { return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ); } - function getRant( required numeric rantID ){ + function getRant( required rantId ){ return queryExecute( "select * from rants - where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } + where id = :rantId", + { rantId : arguments.rantId } ); } - function delete( required numeric rantID ){ + function delete( required rantId ){ queryExecute( "delete from rants - where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + where id = :rantId", + { rantId : arguments.rantId }, { result : "local.result" } ); return local.result; } - function create( required body, required numeric userID ){ - var now = now(); + function create( required body, required userID ){ + var now = now(); + var newId = createUUID(); queryExecute( "insert into rants - set - body = :body, - userID = :userID, - createdDate = :createdDate, - modifiedDate = :modifiedDate + set + id = :rantId, + body = :body, + userID = :userID ", { - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + rantId : newId, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + userID : arguments.userId }, { result : "local.result" } ); + local.result.generatedKey = newId; return local.result; } - function update( required body, required numeric rantId ){ + function update( required body, required rantId ){ var now = now(); queryExecute( "update rants - set - body = :body, - modifiedDate = :modifiedDate - where id = :rantID + set + body = :body, + updatedDate = :updatedDate + where id = :rantId ", { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_integer" - }, - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + rantId : arguments.rantId, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v1/models/UserService.cfc b/modules_app/api/modules_app/v1/models/UserService.cfc index cbda85f..91b8b8b 100644 --- a/modules_app/api/modules_app/v1/models/UserService.cfc +++ b/modules_app/api/modules_app/v1/models/UserService.cfc @@ -10,15 +10,12 @@ component singleton accessors="true" { return this; } - function get( required numeric userID ){ + function get( required string userId ){ return queryExecute( "select * from users - where id = :userID", + where id = :userId", { - userID : { - value : "#userID#", - type : "cf_sql_numeric" - } + userId : arguments.userId } ); } diff --git a/tests/specs/integration/api-v1/EchoTests.cfc b/tests/specs/integration/api-v1/EchoTests.cfc index 81aa17b..96f0637 100644 --- a/tests/specs/integration/api-v1/EchoTests.cfc +++ b/tests/specs/integration/api-v1/EchoTests.cfc @@ -14,48 +14,51 @@ * * eventArguments : The struct of args to pass to the event * * renderResults : Render back the results of the event *******************************************************************************/ -component - extends="coldbox.system.testing.BaseTestCase" - -{ +component extends="coldbox.system.testing.BaseTestCase" { /*********************************** LIFE CYCLE Methods ***********************************/ - function beforeAll() { + function beforeAll(){ super.beforeAll(); // do your own stuff here } - function afterAll() { + function afterAll(){ // do your own stuff here super.afterAll(); } /*********************************** BDD SUITES ***********************************/ - function run() { - describe( "My RESTFUl Service", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "My RESTFUl Service v1", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - it( "can handle invalid HTTP Calls", function() { + it( "can handle invalid HTTP Calls", function(){ var event = execute( - event = "v1:echo.onInvalidHTTPMethod", - renderResults = true, - eventArguments = { faultAction: "test" } + event = "v1:echo.onInvalidHTTPMethod", + renderResults = true, + eventArguments = { faultAction : "test" } ); var response = event.getPrivateValue( "response" ); expect( response.getError() ).toBeTrue(); expect( response.getStatusCode() ).toBe( 405 ); } ); - it( "can handle global exceptions", function() { + it( "can handle global exceptions", function(){ var event = execute( - event = "v1:echo.onError", - renderResults = true, - eventArguments = { exception: { message: "unit test", detail: "unit test", stacktrace: "" } } + event = "v1:echo.onError", + renderResults = true, + eventArguments = { + exception : { + message : "unit test", + detail : "unit test", + stacktrace : "" + } + } ); var response = event.getPrivateValue( "response" ); @@ -63,15 +66,15 @@ component expect( response.getStatusCode() ).toBe( 500 ); } ); - it( "can handle an echo", function() { - var event = this.request( "/api/v1/echo/index" ); + it( "can handle an echo", function(){ + var event = this.request( "/api/v1/echo/index" ); var response = event.getPrivateValue( "response" ); expect( response.getError() ).toBeFalse(); expect( response.getData() ).toBe( "Welcome to my ColdBox RESTFul Service V1" ); } ); - it( "can handle missing actions", function() { - var event = this.request( "/api/v1/echo/bogus" ); + it( "can handle missing actions", function(){ + var event = this.request( "/api/v1/echo/bogus" ); var response = event.getPrivateValue( "response" ); expect( response.getError() ).tobeTrue(); expect( response.getStatusCode() ).toBe( 405 ); diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index 8d7a275..8b28e7d 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -1,17 +1,17 @@ -component extends="tests.resources.BaseTest" { +component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V1 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V1 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v1/rants/list", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v1/rants/list" ); + story( "Get a list of Rants", function(){ + given( "I make a get call to /api/v1/rants/list", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v1/rants/list" ); var returnedJSON = event.getRenderData().data; expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); @@ -30,11 +30,11 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v1/rants/view", function() { - when( "I pass an no rantID", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v1/rants/view" ); + story( "Get an individual Rant", function(){ + given( "I make a get call to /api/v1/rants/view", function(){ + when( "I pass an no rantID", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v1/rants/view" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -47,9 +47,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v1/rants/view?rantID=abc" ); + when( "I pass an invalid rantID", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v1/rants/view?rantID=abc" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -57,13 +57,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var event = get( "/api/v1/rants/view?rantID=-57" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var event = get( "/api/v1/rants/view?rantID=#createUUID()#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -75,9 +75,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var event = get( "/api/v1/rants/view?rantID=7" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v1/rants/view?rantID=#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -85,7 +86,7 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); - expect( returnedJSON.data.id ).toBe( 7 ); + expect( returnedJSON.data.id ).toBe( testRantId ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -94,12 +95,11 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Create a Rant", function() { - given( "I make a get call to /api/v1/rants/create", function() { - when( "Using a get method", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v1/rants/create" ); + story( "Create a Rant", function(){ + given( "I make a get call to /api/v1/rants/create", function(){ + when( "Using a get method", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -111,9 +111,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/create" ); + when( "Including no body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -125,9 +125,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/create", { "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/create", { "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -139,9 +139,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/create", { "body": "xsxswxws" } ); + when( "Including no userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/create", { "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -153,9 +153,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/create", { "body": "xsxswxws", "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -163,13 +163,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/create", { "body": "xsxswxws", "userID": "abc" } ); + when( "Including a non uuid userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -177,13 +177,16 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var event = post( "/api/v1/rants/create", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var event = post( + "/api/v1/rants/create", + { "body" : "xsxswxws", "userID" : "#createUUID()#" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -195,9 +198,16 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v1/rants/create", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( + "/api/v1/rants/create", + { + "body" : "I am a integration test rant! Do it!", + "userID" : "#testUserId#" + } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -215,28 +225,11 @@ component extends="tests.resources.BaseTest" { } ); } ); - - - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v1/rants/save", function() { - xwhen( "Using a get method", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v1/rants/save" ); - var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); - expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (update): GET" ); - } ); - } ); - - - when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save" ); + story( "Update a Rant", function(){ + given( "I make a get call to /api/v1/rants/save", function(){ + when( "Including no body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/save" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -248,9 +241,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save", { "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/save", { "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -262,9 +255,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no rantID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save", { "body": "abc" } ); + when( "Including no rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/save", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -276,9 +269,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty rantID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save", { "body": "abc", "rantID": "" } ); + when( "Including an empty rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -286,13 +279,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save", { "body": "abc", "rantID": "abc" } ); + when( "Including a non UUID rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -300,13 +293,16 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var event = post( "/api/v1/rants/save", { "body": "xsxswxws", "rantID": "1" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var event = post( + "/api/v1/rants/save", + { "body" : "xsxswxws", "rantID" : "#createUUID()#" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -318,9 +314,13 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/save", { "body": "xsxswxws", "rantID": "7" } ); + when( "Including no userID param and a valid rant ID", function(){ + then( "I will get a 412 error", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = post( + "/api/v1/rants/save", + { "body" : "xsxswxws", "rantID" : "#testRant.id#" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -332,11 +332,16 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { - var event = post( + when( "Including an empty userID param and valid rantId", function(){ + then( "I will get a 412 error", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = post( "/api/v1/rants/save", - { "body": "xsxswxws", "rantID": "7", "userID": "" } + { + "body" : "xsxswxws", + "rantID" : "#testRant.id#", + "userID" : "" + } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -345,15 +350,20 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { - var event = post( + when( "Including a non UUID userID param and a valid rant Id", function(){ + then( "I will get a 412 error", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = post( "/api/v1/rants/save", - { "body": "xsxswxws", "rantID": "7", "userID": "abc" } + { + "body" : "xsxswxws", + "rantID" : "#testRant.id#", + "userID" : "abc" + } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -362,15 +372,20 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var event = post( + when( "Including valid userID for a non existing User and a valid rantId", function(){ + then( "I will get a 404 error", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = post( "/api/v1/rants/save", - { "body": "xsxswxws", "rantID": "7", "userID": "1" } + { + "body" : "xsxswxws", + "rantID" : "#testRant.id#", + "userID" : "#createUUID()#" + } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -383,11 +398,16 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { - var event = post( + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = post( "/api/v1/rants/save", - { "body": "xsxswxws", "rantID": "7", "userID": "5" } + { + "body" : "xsxswxws", + "rantID" : "#testRant.id#", + "userID" : "#testRant.userId#" + } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -403,12 +423,11 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v1/rants/delete", function() { - when( "Using a get method", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v1/rants/delete" ); + story( "Delete a Rant", function(){ + given( "I make a get call to /api/v1/rants/delete", function(){ + when( "Using a get method", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -420,9 +439,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v1/rants/delete" ); + when( "Using a post method", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -436,9 +455,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no rantID param", function() { - then( "I will get a 412 error", function() { - var event = delete( "/api/v1/rants/delete", { "body": "abc" } ); + when( "Including no rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = delete( "/api/v1/rants/delete", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -450,9 +469,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty rantID param", function() { - then( "I will get a 412 error", function() { - var event = delete( "/api/v1/rants/delete", { "rantID": "" } ); + when( "Including an empty rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = delete( "/api/v1/rants/delete", { "rantID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -460,13 +479,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { - var event = delete( "/api/v1/rants/delete", { "rantID": "abc" } ); + when( "Including a non UUID rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = delete( "/api/v1/rants/delete", { "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -474,13 +493,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be numeric" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var event = delete( "/api/v1/rants/delete", { "rantID": "1" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var event = delete( "/api/v1/rants/delete", { "rantID" : "#createUUID()#" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -492,25 +511,24 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { - var event = post( - "/api/v1/rants/create", - { "body": "New Rant Created to Delete", "userID": "5" } - ); - var returnedJSON = event.getRenderData().data; + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ + var testUserId = queryExecute( "select id from users limit 1" ).id; + var testRantId = getInstance( "RantService@v1" ).create( + "my integration test", + testUserId + ).generatedKey; - setup(); - var event2 = delete( "/api/v1/rants/delete", { "rantID": returnedJSON.data.rantID } ); - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + var event = delete( "/api/v1/rants/delete", { "rantID" : testRantId } ); + var returnedJSON = event.getRenderData().data; + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); From 442caf41d0f2d56d45614ed13a846905012f0003 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 14 Jul 2022 15:50:54 -0500 Subject: [PATCH 40/75] v2 module done. --- .../api/modules_app/v1/models/RantService.cfc | 2 +- .../api/modules_app/v1/models/UserService.cfc | 6 +- .../api/modules_app/v2/ModuleConfig.cfc | 2 +- .../api/modules_app/v2/config/Router.cfc | 12 +- .../api/modules_app/v2/handlers/Rants.cfc | 19 +- .../api/modules_app/v2/models/RantService.cfc | 101 +++----- .../api/modules_app/v2/models/UserService.cfc | 22 +- tests/specs/integration/api-v2/RantsTest.cfc | 239 +++++++++--------- 8 files changed, 184 insertions(+), 219 deletions(-) diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index 172ca5f..d7e3231 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -1,5 +1,5 @@ /** - * I am the Rant Service + * I am the Rant Service V1 */ component singleton accessors="true" { diff --git a/modules_app/api/modules_app/v1/models/UserService.cfc b/modules_app/api/modules_app/v1/models/UserService.cfc index 91b8b8b..05b1dd7 100644 --- a/modules_app/api/modules_app/v1/models/UserService.cfc +++ b/modules_app/api/modules_app/v1/models/UserService.cfc @@ -1,5 +1,5 @@ /** - * I am the User Service + * I am the User Service V1 */ component singleton accessors="true" { @@ -14,9 +14,7 @@ component singleton accessors="true" { return queryExecute( "select * from users where id = :userId", - { - userId : arguments.userId - } + { userId : arguments.userId } ); } diff --git a/modules_app/api/modules_app/v2/ModuleConfig.cfc b/modules_app/api/modules_app/v2/ModuleConfig.cfc index 67fbf00..fa6478e 100644 --- a/modules_app/api/modules_app/v2/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v2/ModuleConfig.cfc @@ -1,5 +1,5 @@ /** - * Module Config + * v2 Module Config */ component { diff --git a/modules_app/api/modules_app/v2/config/Router.cfc b/modules_app/api/modules_app/v2/config/Router.cfc index 98d3791..23dd4d1 100644 --- a/modules_app/api/modules_app/v2/config/Router.cfc +++ b/modules_app/api/modules_app/v2/config/Router.cfc @@ -1,13 +1,15 @@ component { function configure(){ - post( "/rants/create", "rants.create" ) - route( "/rants/:rantID/delete", "rants.delete" ) - route( "/rants/:rantID/save", "rants.save" ) + // CRUD + get( "/rants", "rants.list" ) get( "/rants/:rantID", "rants.view" ) - route( "/rants", "rants.list" ) + post( "/rants/create", "rants.create" ) + delete( "/rants/:rantID/delete", "rants.delete" ) + put( "/rants/:rantID/save", "rants.save" ) + + // Entry Point route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); } } diff --git a/modules_app/api/modules_app/v2/handlers/Rants.cfc b/modules_app/api/modules_app/v2/handlers/Rants.cfc index 9e8975c..5b13564 100644 --- a/modules_app/api/modules_app/v2/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v2/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -16,12 +21,11 @@ component extends="coldbox.system.RestHandler" { /** * Returns a single Rant - * */ function view( event, rc, prc ){ var validationResults = validate( target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + constraints = { rantID : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); @@ -38,12 +42,11 @@ component extends="coldbox.system.RestHandler" { /** * Deletes a single Rant - * */ function delete( event, rc, prc ){ var validationResults = validate( target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + constraints = { rantID : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); @@ -60,13 +63,12 @@ component extends="coldbox.system.RestHandler" { /** * Creates a new Rant - * */ function create( event, rc, prc ){ var validationResults = validate( target = rc, constraints = { - userID : { required : true, type : "numeric" }, + userID : { required : true, type : "uuid" }, body : { required : true } } ); @@ -91,15 +93,14 @@ component extends="coldbox.system.RestHandler" { /** * Updates an Existing Rant - * */ function save( event, rc, prc ){ var validationResults = validate( target = rc, constraints = { - rantID : { required : true, type : "numeric" }, + rantID : { required : true, type : "uuid" }, body : { required : true }, - userID : { required : true, type : "numeric" } + userID : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index 388ae29..915a573 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -11,73 +11,52 @@ component singleton accessors="true" { } array function list(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ) - .reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); + return queryExecute( + "select * from rants ORDER BY createdDate DESC", + {}, + { returnType : "array" } + ); } - struct function get( required numeric rantID ){ + struct function get( required rantId ){ return queryExecute( "select * from rants - where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } + where id = :rantId + ", + { rantId : arguments.rantId } ).reduce( ( result, row ) => { return row; }, {} ); } - function delete( required numeric rantID ){ + function delete( required rantId ){ queryExecute( "delete from rants - where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + where id = :rantId", + { rantId : arguments.rantId }, { result : "local.result" } ); return local.result; } - function create( required body, required numeric userID ){ - var now = now(); + function create( required body, required userId ){ + var now = now(); + var newKey = createUUID(); queryExecute( "insert into rants - set - body = :body, - userID = :userID, - createdDate = :createdDate, - modifiedDate = :modifiedDate + set + id = :rantId, + body = :body, + userId = :userId, ", { - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + rantId : newKey, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + userId : arguments.userId }, { result : "local.result" } ); + local.result.generatedKey = newKey; return local.result; } @@ -85,41 +64,27 @@ component singleton accessors="true" { var now = now(); queryExecute( "update rants - set - body = :body, - modifiedDate = :modifiedDate - where id = :rantID + set + body = :body, + modifiedDate = :modifiedDate + where id = :rantId ", { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_integer" - }, - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + rantId : arguments.rantId, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + modifiedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); return local.result; } - boolean function exists( required numeric rantID ){ + boolean function exists( required rantId ){ return booleanFormat( queryExecute( "select id from rants - where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } + where id = :rantId", + { rantId : arguments.rantId } ).len() ) } diff --git a/modules_app/api/modules_app/v2/models/UserService.cfc b/modules_app/api/modules_app/v2/models/UserService.cfc index 6e89209..70545a2 100644 --- a/modules_app/api/modules_app/v2/models/UserService.cfc +++ b/modules_app/api/modules_app/v2/models/UserService.cfc @@ -10,30 +10,20 @@ component singleton accessors="true" { return this; } - function get( required numeric userID ){ + struct function get( required string userId ){ return queryExecute( "select * from users - where id = :userID", - { - userID : { - value : "#userID#", - type : "cf_sql_numeric" - } - } + where id = :userId", + { userId : arguments.userId } ).reduce( ( result, row ) => row, {} ); } - boolean function exists( required numeric userID ){ + boolean function exists( required string userId ){ return booleanFormat( queryExecute( "select id from users - where id = :userID", - { - userID : { - value : "#userID#", - type : "cf_sql_numeric" - } - } + where id = :userId", + { userId : arguments.userId } ).len() ) } diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 4dd2cd5..23e8cbf 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -1,17 +1,17 @@ -component extends="tests.resources.BaseTest" { +component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V2 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V2 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v2/rants", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v2/rants" ); + story( "Get a list of Rants", function(){ + given( "I make a get call to /api/v2/rants", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v2/rants" ); var returnedJSON = event.getRenderData().data; expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); @@ -29,12 +29,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v2/rants/:rantID", function() { - when( "I pass an invalid rantID", function() { - then( "I will get a 412 error", function() { - var rantID = "x" - var event = get( "/api/v2/rants/#rantID#" ); + story( "Get an individual Rant", function(){ + given( "I make a get call to /api/v2/rants/:rantID", function(){ + when( "I pass an invalid rantID", function(){ + then( "I will get a 412 error", function(){ + var rantID = "x" + var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -48,10 +48,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var rantID = "1" - var event = get( "/api/v2/rants/#rantID#" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1" + var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -63,10 +63,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var rantID = 7; - var event = get( "/api/v2/rants/#rantID#" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var rantID = 7; + var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -84,11 +84,11 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function() { - given( "I make a get call to /api/v2/rants/create", function() { - when( "Using a get method", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v2/rants/create" ); + story( "Create a Rant", function(){ + given( "I make a get call to /api/v2/rants/create", function(){ + when( "Using a get method", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v2/rants/create" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -100,9 +100,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v2/rants/create", {} ); + when( "Including no userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v2/rants/create", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -114,9 +114,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v2/rants/create", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v2/rants/create", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -128,9 +128,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v2/rants/create", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v2/rants/create", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -144,9 +144,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v2/rants/create", { "userID": "5" } ); + when( "Including no body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v2/rants/create", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -158,9 +158,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var event = post( "/api/v2/rants/create", { "userID": "5", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 412 error", function(){ + var event = post( "/api/v2/rants/create", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -172,9 +172,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var event = post( "/api/v2/rants/create", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var event = post( "/api/v2/rants/create", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -186,9 +186,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v2/rants/create", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var event = post( "/api/v2/rants/create", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -208,12 +208,12 @@ component extends="tests.resources.BaseTest" { - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v2/rants/:rantID/save", function() { - xwhen( "Using a get method", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; - var event = get( "/api/v2/rants/#rantID#/save" ); + story( "Update a Rant", function(){ + given( "I make a get call to /api/v2/rants/:rantID/save", function(){ + xwhen( "Using a get method", function(){ + then( "I will get a 412 error", function(){ + var rantID = "1"; + var event = get( "/api/v2/rants/#rantID#/save" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -225,10 +225,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 412 error", function() { - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", {} ); + when( "Including no userID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "7"; + var event = post( "/api/v2/rants/#rantID#/save", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -240,10 +240,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 412 error", function() { - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "7"; + var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -255,10 +255,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 412 error", function() { - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "7"; + var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -273,10 +273,10 @@ component extends="tests.resources.BaseTest" { } ); - when( "Including no body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "1" } ); + when( "Including no body param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "1"; + var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -288,10 +288,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 412 error", function() { - var rantID = "1"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "1", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "1"; + var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -303,10 +303,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { - var rantID = "abc"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "1", "body": "abc" } ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "abc"; + var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -320,10 +320,13 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "body": "xsxswxws", "userID": "1" } ); + var event = post( + "/api/v2/rants/#rantID#/save", + { "body" : "xsxswxws", "userID" : "1" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -335,10 +338,13 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ var rantID = "1"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID": "5", "body": "xsxswxws" } ); + var event = post( + "/api/v2/rants/#rantID#/save", + { "userID" : "5", "body" : "xsxswxws" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -354,10 +360,13 @@ component extends="tests.resources.BaseTest" { - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "body": "xsxswxws", "userID": "5" } ); + var event = post( + "/api/v2/rants/#rantID#/save", + { "body" : "xsxswxws", "userID" : "5" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -373,11 +382,11 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v2/rants/:rantID/delete", function() { - when( "Using a get method", function() { - then( "I will get a 412 error", function() { - var event = get( "/api/v2/rants/a/delete" ); + story( "Delete a Rant", function(){ + given( "I make a get call to /api/v2/rants/:rantID/delete", function(){ + when( "Using a get method", function(){ + then( "I will get a 412 error", function(){ + var event = get( "/api/v2/rants/a/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -389,9 +398,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no rantID param", function() { - then( "I will get a 412 error", function() { - var event = delete( "/api/v2/rants/delete" ); + when( "Including no rantID param", function(){ + then( "I will get a 412 error", function(){ + var event = delete( "/api/v2/rants/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -406,10 +415,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty rantID param", function() { - then( "I will get a 412 error", function() { - var rantID = ""; - var event = delete( "/api/v2/rants/#rantID#/delete" ); + when( "Including an empty rantID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = ""; + var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -423,10 +432,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a space for rantID param", function() { - then( "I will get a 412 error", function() { - var rantID = " "; - var event = delete( "/api/v2/rants/#rantID#/delete" ); + when( "Including a space for rantID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = " "; + var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -438,10 +447,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 412 error", function() { - var rantID = "abc"; - var event = delete( "/api/v2/rants/#rantID#/delete" ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 412 error", function(){ + var rantID = "abc"; + var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -455,10 +464,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = 1; - var event = delete( "/api/v2/rants/#rantID#/delete" ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = 1; + var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -471,11 +480,11 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ var event = post( "/api/v2/rants/create", - { "body": "New Rant Created to Delete", "userID": "5" } + { "body" : "New Rant Created to Delete", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; From 1e9d354d02efb777a496a81dcb0a0a23743bb457 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 14 Jul 2022 17:25:44 -0500 Subject: [PATCH 41/75] v2 finalized --- Application.cfc | 38 +-- config/CacheBox.cfc | 6 +- config/Coldbox.cfc | 21 +- config/Router.cfc | 4 +- config/Scheduler.cfc | 9 +- config/WireBox.cfc | 6 +- modules_app/api/ModuleConfig.cfc | 18 +- modules_app/api/config/Router.cfc | 2 +- .../api/modules_app/v2/config/Router.cfc | 4 +- .../api/modules_app/v2/models/RantService.cfc | 10 +- .../api/modules_app/v3/handlers/Rants.cfc | 11 +- .../api/modules_app/v3/models/BaseService.cfc | 19 +- .../api/modules_app/v3/models/RantService.cfc | 63 +---- .../api/modules_app/v3/models/UserService.cfc | 7 +- .../api/modules_app/v4/handlers/Rants.cfc | 23 +- .../api/modules_app/v4/models/BaseService.cfc | 21 +- .../api/modules_app/v4/models/Rant.cfc | 20 +- .../api/modules_app/v4/models/RantService.cfc | 63 ++--- .../api/modules_app/v4/models/User.cfc | 23 +- .../api/modules_app/v4/models/UserService.cfc | 9 +- .../api/modules_app/v5/handlers/Rants.cfc | 27 +- .../api/modules_app/v5/models/BaseEntity.cfc | 44 ++-- .../api/modules_app/v5/models/BaseService.cfc | 28 +-- .../api/modules_app/v5/models/Rant.cfc | 22 +- .../api/modules_app/v5/models/RantService.cfc | 63 ++--- .../api/modules_app/v5/models/User.cfc | 14 +- .../api/modules_app/v5/models/UserService.cfc | 9 +- .../api/modules_app/v6/handlers/Rants.cfc | 34 +-- .../api/modules_app/v6/models/BaseEntity.cfc | 44 ++-- .../api/modules_app/v6/models/BaseService.cfc | 28 +-- .../api/modules_app/v6/models/Rant.cfc | 22 +- .../api/modules_app/v6/models/RantService.cfc | 63 ++--- .../api/modules_app/v6/models/User.cfc | 14 +- .../api/modules_app/v6/models/UserService.cfc | 9 +- tests/specs/integration/api-v2/RantsTest.cfc | 144 +++++------ tests/specs/integration/api-v3/RantsTest.cfc | 231 ++++++++--------- tests/specs/integration/api-v4/RantsTest.cfc | 235 +++++++++--------- tests/specs/integration/api-v5/RantsTest.cfc | 227 ++++++++--------- tests/specs/integration/api-v6/RantsTest.cfc | 229 ++++++++--------- 39 files changed, 851 insertions(+), 1013 deletions(-) diff --git a/Application.cfc b/Application.cfc index ca66bbe..06e86d2 100644 --- a/Application.cfc +++ b/Application.cfc @@ -1,18 +1,19 @@ /** -* Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -*/ -component{ + * Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + */ +component { + // Application properties - this.name = hash( getCurrentTemplatePath() ); + this.name = hash( getCurrentTemplatePath() ); this.sessionManagement = true; - this.sessionTimeout = createTimeSpan(0,0,30,0); - this.setClientCookies = true; - this.datasource = "fluentAPI"; + this.sessionTimeout = createTimespan( 0, 0, 30, 0 ); + this.setClientCookies = true; + this.datasource = "fluentAPI"; // Important - this.serialization.preserveCaseForStructKey = true; + this.serialization.preserveCaseForStructKey = true; this.serialization.preserveCaseForQueryColumn = true; // COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP @@ -20,13 +21,18 @@ component{ // The web server mapping to this application. Used for remote purposes or static purposes COLDBOX_APP_MAPPING = ""; // COLDBOX PROPERTIES - COLDBOX_CONFIG_FILE = ""; + COLDBOX_CONFIG_FILE = ""; // COLDBOX APPLICATION KEY OVERRIDE - COLDBOX_APP_KEY = ""; + COLDBOX_APP_KEY = ""; // application start public boolean function onApplicationStart(){ - application.cbBootstrap = new coldbox.system.Bootstrap( COLDBOX_CONFIG_FILE, COLDBOX_APP_ROOT_PATH, COLDBOX_APP_KEY, COLDBOX_APP_MAPPING ); + application.cbBootstrap = new coldbox.system.Bootstrap( + COLDBOX_CONFIG_FILE, + COLDBOX_APP_ROOT_PATH, + COLDBOX_APP_KEY, + COLDBOX_APP_MAPPING + ); application.cbBootstrap.loadColdbox(); return true; } @@ -49,11 +55,11 @@ component{ } public void function onSessionEnd( struct sessionScope, struct appScope ){ - arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection=arguments ); + arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection = arguments ); } public boolean function onMissingTemplate( template ){ - return application.cbBootstrap.onMissingTemplate( argumentCollection=arguments ); + return application.cbBootstrap.onMissingTemplate( argumentCollection = arguments ); } -} \ No newline at end of file +} diff --git a/config/CacheBox.cfc b/config/CacheBox.cfc index 5abc240..0d8e51f 100644 --- a/config/CacheBox.cfc +++ b/config/CacheBox.cfc @@ -1,8 +1,9 @@ -component{ +component { + /** * Configure CacheBox for ColdBox Application Operation */ - function configure() { + function configure(){ /** * -------------------------------------------------------------------------- * CacheBox Configuration (https://cachebox.ortusbooks.com) @@ -61,4 +62,5 @@ } }; } + } diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 63cd536..228eb65 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -1,4 +1,5 @@ -component{ +component { + /** * Configure the ColdBox App For Production */ @@ -146,7 +147,6 @@ // If not empty, convert all date/times to the specific timezone convertToTimezone : "UTC" }, - /** * -------------------------------------------------------------------------- * cbSwagger Settings @@ -203,7 +203,7 @@ // Define your security schemes here // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject "securitySchemes" : { - // "ApiKeyAuth" : { + // "ApiKeyAuth" : { // "type" : "apiKey", // "description" : "User your JWT as an Api Key for security", // "name" : "x-api-key", @@ -226,8 +226,6 @@ // { "UserSecurity" : [] } // ] } - - }; } @@ -236,25 +234,25 @@ */ function development(){ coldbox.handlersIndexAutoReload = true; - coldbox.handlerCaching = false; + coldbox.handlerCaching = false; coldbox.reinitpassword = ""; - coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; + coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; // Debugger Settings variables.modulesettings.cbdebugger = { // This flag enables/disables the tracking of request data to our storage facilities // To disable all tracking, turn this master key off - enabled : true,//getSystemSetting( "CBDEBUGGER_ENABLED", false ), + enabled : true, // getSystemSetting( "CBDEBUGGER_ENABLED", false ), // This setting controls if you will activate the debugger for visualizations ONLY // The debugger will still track requests even in non debug mode. - debugMode : true, + debugMode : true, // The URL password to use to activate it on demand - debugPassword : "cb", + debugPassword : "cb", // This flag enables/disables the end of request debugger panel docked to the bottom of the page. // If you disable it, then the only way to visualize the debugger is via the `/cbdebugger` endpoint requestPanelDock : true, // Request Tracker Options - requestTracker : { + requestTracker : { storage : "cachebox", cacheName : "template", trackDebuggerEvents : false, @@ -330,4 +328,5 @@ async : { enabled : true, expanded : false } }; } + } diff --git a/config/Router.cfc b/config/Router.cfc index 7d5a3ee..bfa57f8 100644 --- a/config/Router.cfc +++ b/config/Router.cfc @@ -1,6 +1,6 @@ component { - function configure() { + function configure(){ // Set Full Rewrites setFullRewrites( true ); @@ -15,7 +15,7 @@ component { */ // A nice healthcheck route example - route( "/healthcheck", function( event, rc, prc ) { + route( "/healthcheck", function( event, rc, prc ){ return "Ok!"; } ); diff --git a/config/Scheduler.cfc b/config/Scheduler.cfc index be0de30..b74d2e3 100644 --- a/config/Scheduler.cfc +++ b/config/Scheduler.cfc @@ -3,7 +3,7 @@ component { /** * Configure the ColdBox Scheduler */ - function configure() { + function configure(){ /** * -------------------------------------------------------------------------- * Configuration Methods @@ -22,7 +22,6 @@ component { * You register tasks with the task() method and get back a ColdBoxScheduledTask object * that you can use to register your tasks configurations. */ - } /** @@ -40,7 +39,7 @@ component { /** * Called whenever ANY task fails * - * @task The task that got executed + * @task The task that got executed * @exception The ColdFusion exception object */ function onAnyTaskError( required task, required exception ){ @@ -49,7 +48,7 @@ component { /** * Called whenever ANY task succeeds * - * @task The task that got executed + * @task The task that got executed * @result The result (if any) that the task produced */ function onAnyTaskSuccess( required task, result ){ @@ -66,7 +65,7 @@ component { /** * Called after ANY task runs * - * @task The task that got executed + * @task The task that got executed * @result The result (if any) that the task produced */ function afterAnyTask( required task, result ){ diff --git a/config/WireBox.cfc b/config/WireBox.cfc index 4cf9ce4..ed1ef2a 100644 --- a/config/WireBox.cfc +++ b/config/WireBox.cfc @@ -1,8 +1,9 @@ -component extends = "coldbox.system.ioc.config.Binder"{ +component extends="coldbox.system.ioc.config.Binder" { + /** * Configure WireBox, that's it! */ - function configure() { + function configure(){ /** * -------------------------------------------------------------------------- * WireBox Configuration (https://wirebox.ortusbooks.com) @@ -33,4 +34,5 @@ // Map Bindings below } + } diff --git a/modules_app/api/ModuleConfig.cfc b/modules_app/api/ModuleConfig.cfc index 813a59c..d1badc3 100644 --- a/modules_app/api/ModuleConfig.cfc +++ b/modules_app/api/ModuleConfig.cfc @@ -4,37 +4,37 @@ component { // Module Properties - this.title = "api"; + this.title = "api"; this.description = "Base API Module"; - this.version = "1.0.0"; + this.version = "1.0.0"; // Module Entry Point in the URI: http://yourapp/api - this.entryPoint = "api"; + this.entryPoint = "api"; // Inheritable entry point. this.inheritEntryPoint = true; // Model Namespace - this.modelNamespace = "api"; + this.modelNamespace = "api"; // CF Mapping - this.cfmapping = "api"; + this.cfmapping = "api"; // Module Dependencies - this.dependencies = []; + this.dependencies = []; /** * Configure the module */ - function configure() { + function configure(){ } /** * Fired when the module is registered and activated. */ - function onLoad() { + function onLoad(){ } /** * Fired when the module is unregistered and unloaded */ - function onUnload() { + function onUnload(){ } } diff --git a/modules_app/api/config/Router.cfc b/modules_app/api/config/Router.cfc index 02ec5de..e8d17c3 100644 --- a/modules_app/api/config/Router.cfc +++ b/modules_app/api/config/Router.cfc @@ -1,6 +1,6 @@ component { - function configure() { + function configure(){ } } diff --git a/modules_app/api/modules_app/v2/config/Router.cfc b/modules_app/api/modules_app/v2/config/Router.cfc index 23dd4d1..e8d991c 100644 --- a/modules_app/api/modules_app/v2/config/Router.cfc +++ b/modules_app/api/modules_app/v2/config/Router.cfc @@ -2,11 +2,11 @@ component { function configure(){ // CRUD - get( "/rants", "rants.list" ) - get( "/rants/:rantID", "rants.view" ) post( "/rants/create", "rants.create" ) delete( "/rants/:rantID/delete", "rants.delete" ) put( "/rants/:rantID/save", "rants.save" ) + get( "/rants/:rantID", "rants.view" ) + get( "/rants", "rants.list" ) // Entry Point route( "/", "echo.index" ); diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index 915a573..bffd7f2 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -47,7 +47,7 @@ component singleton accessors="true" { set id = :rantId, body = :body, - userId = :userId, + userId = :userId ", { rantId : newKey, @@ -66,13 +66,13 @@ component singleton accessors="true" { "update rants set body = :body, - modifiedDate = :modifiedDate + updatedDate = :updatedDate where id = :rantId ", { - rantId : arguments.rantId, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - modifiedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } + rantId : arguments.rantId, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index c3c3ed4..7d93e10 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -20,12 +20,7 @@ component extends="coldbox.system.RestHandler" { * */ function show( event, rc, prc ){ - validateOrFail( - target = rc, - constraints = { - rantID : { required : true, type : "numeric" } - } - ); + validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); prc.response.setData( rantService.getOrFail( rc.rantID ) ); } @@ -36,9 +31,7 @@ component extends="coldbox.system.RestHandler" { function delete( event, rc, prc ){ var validationResults = validateOrFail( target = rc, - constraints = { - rantID : { required : true, type : "numeric" } - } + constraints = { rantID : { required : true, type : "numeric" } } ); rantService.existsOrFail( rc.rantID ) rantService.delete( rc.rantID ); diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index c8ec834..236561f 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -44,12 +44,7 @@ component accessors="true" { queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { - id : { - value : arguments[ 1 ], - cfsqltype : "cf_sql_numeric" - } - } + { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } ).len() ) } @@ -58,31 +53,27 @@ component accessors="true" { * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * * @return Returns true if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( - type = "EntityNotFound", - message = "#entityName# Not Found" - ); + throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } /** * Query and load an entity if possible, else throw an error * * @return Returns the Entity if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( maybeEntity.isEmpty() ) { - throw( - type = "EntityNotFound", - message = "#getEntityName()# Not Found" - ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } diff --git a/modules_app/api/modules_app/v3/models/RantService.cfc b/modules_app/api/modules_app/v3/models/RantService.cfc index 0bec065..4d3951f 100644 --- a/modules_app/api/modules_app/v3/models/RantService.cfc +++ b/modules_app/api/modules_app/v3/models/RantService.cfc @@ -21,10 +21,7 @@ component } array function list(){ - return queryExecute( - "select * from rants ORDER BY createdDate DESC", - {} - ).reduce( ( result, row ) => { + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); @@ -34,12 +31,7 @@ component return queryExecute( "select * from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => row, {} ); } @@ -47,21 +39,13 @@ component queryExecute( "delete from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; } - function create( - required body, - required numeric userID - ){ + function create( required body, required numeric userID ){ var now = now(); queryExecute( "insert into rants @@ -69,25 +53,13 @@ component body = :body, userID = :userID, createdDate = :createdDate, - modifiedDate = :modifiedDate + updatedDate = :updatedDate ", { - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" }, + createdDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" }, + updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); @@ -100,22 +72,13 @@ component "update rants set body = :body, - modifiedDate = :modifiedDate + updatedDate = :updatedDate where id = :rantID ", { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_integer" - }, - body : { - value : "#body#", - cfsqltype : "cf_sql_longvarchar" - }, - modifiedDate : { - value : "#now#", - cfsqltype : "cf_sql_timestamp" - } + rantID : { value : "#rantID#", cfsqltype : "cf_sql_integer" }, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v3/models/UserService.cfc b/modules_app/api/modules_app/v3/models/UserService.cfc index 09aac04..ea3d567 100644 --- a/modules_app/api/modules_app/v3/models/UserService.cfc +++ b/modules_app/api/modules_app/v3/models/UserService.cfc @@ -24,12 +24,7 @@ component return queryExecute( "select * from users where id = :userID", - { - userID : { - value : "#userID#", - type : "cf_sql_numeric" - } - } + { userID : { value : "#userID#", type : "cf_sql_numeric" } } ).reduce( ( result, row ) => row, {} ); } diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 26a1cdc..986afb1 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -10,12 +10,9 @@ component extends="coldbox.system.RestHandler" { this.prehandler_only = "show,delete,update"; any function preHandler( event, rc, prc, action, eventArguments ){ - try{ - validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - } catch( any e ){ + try { + validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); + } catch ( any e ) { arguments.exception = e; this.onValidationException( argumentCollection = arguments ); } @@ -25,9 +22,7 @@ component extends="coldbox.system.RestHandler" { * Returns a list of Rants */ any function index( event, rc, prc ){ - prc.response.setData( - rantService.list().map( ( rant ) => rant.getMemento() ) - ); + prc.response.setData( rantService.list().map( ( rant ) => rant.getMemento() ) ); } /** @@ -53,10 +48,7 @@ component extends="coldbox.system.RestHandler" { function create( event, rc, prc ){ var rant = rantService.new(); - validateOrFail( - target = rc, - constraints = rant.constraints - ); + validateOrFail( target = rc, constraints = rant.constraints ); userService.existsOrFail( rc.userID ); @@ -75,10 +67,7 @@ component extends="coldbox.system.RestHandler" { function update( event, rc, prc ){ var rant = rantService.getOrFail( rc.rantId ); - validateOrFail( - target = rc, - constraints = rant.constraints - ); + validateOrFail( target = rc, constraints = rant.constraints ); userService.existsOrFail( rc.userID ); diff --git a/modules_app/api/modules_app/v4/models/BaseService.cfc b/modules_app/api/modules_app/v4/models/BaseService.cfc index c0e5473..e67deca 100644 --- a/modules_app/api/modules_app/v4/models/BaseService.cfc +++ b/modules_app/api/modules_app/v4/models/BaseService.cfc @@ -48,12 +48,7 @@ component accessors="true" { queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { - id : { - value : arguments[ 1 ], - cfsqltype : "cf_sql_numeric" - } - } + { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } ).len() ) } @@ -62,33 +57,29 @@ component accessors="true" { * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * * @return Returns true if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( - type = "EntityNotFound", - message = "#entityName# Not Found" - ); + throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } /** * Query and load an entity if possible, else throw an error * * @return Returns the Entity if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( !maybeEntity.isLoaded() ) { - throw( - type = "EntityNotFound", - message = "#getEntityName()# Not Found" - ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v4/models/Rant.cfc b/modules_app/api/modules_app/v4/models/Rant.cfc index 680db30..361d678 100644 --- a/modules_app/api/modules_app/v4/models/Rant.cfc +++ b/modules_app/api/modules_app/v4/models/Rant.cfc @@ -7,11 +7,11 @@ component accessors="true" { property name="userService" inject="UserService@v4"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; + property name="userID" type="string"; // Validation Constraints this.constraints = { @@ -45,11 +45,11 @@ component accessors="true" { */ function getMemento(){ return { - "id" : getID(), - "body" : getBody(), - "createdDate" : dateFormat( getCreatedDate(), "long" ), - "modifiedDate" : dateFormat( getModifiedDate(), "long" ), - "userId" : getUserID() + "id" : getID(), + "body" : getBody(), + "createdDate" : dateFormat( getCreatedDate(), "long" ), + "updatedDate" : dateFormat( getUpdatedDate(), "long" ), + "userId" : getUserID() }; } diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index dda06ef..203324b 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -30,15 +30,12 @@ component return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new(), rant ); + return populator.populateFromStruct( new (), rant ); } ); } array function listArray(){ - return queryExecute( - "select * from rants ORDER BY createdDate DESC", - {} - ).reduce( ( result, row ) => { + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); @@ -48,25 +45,15 @@ component return queryExecute( "select * from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -75,7 +62,7 @@ component function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "insert into rants @@ -83,24 +70,24 @@ component body = :body, userID = :userID, createdDate = :createdDate, - modifiedDate = :modifiedDate + updatedDate = :updatedDate ", { body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, userID : { - value : "#arguments.rant.getuserID()#", - cfsqltype : "cf_sql_numeric" + value : "#arguments.rant.getuserID()#", + cfsqltype : "cf_sql_numeric" }, createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" + value : "#arguments.rant.getCreatedDate()#", + cfsqltype : "cf_sql_timestamp" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -111,26 +98,26 @@ component function update( required Rant rant ){ var now = now(); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "update rants set body = :body, - modifiedDate = :modifiedDate + updatedDate = :updatedDate where id = :rantID ", { rantID : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" + value : "#arguments.rant.getID()#", + cfsqltype : "cf_sql_integer" }, body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } diff --git a/modules_app/api/modules_app/v4/models/User.cfc b/modules_app/api/modules_app/v4/models/User.cfc index b23eeab..00265d9 100644 --- a/modules_app/api/modules_app/v4/models/User.cfc +++ b/modules_app/api/modules_app/v4/models/User.cfc @@ -4,13 +4,12 @@ component accessors="true" { // Properties - property name="id" type="string"; - property name="username" type="string"; - property name="email" type="string"; - property name="password" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; - + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; /** * Constructor @@ -31,11 +30,11 @@ component accessors="true" { */ function getMemento(){ return { - "id" : getID(), - "username" : getUsername(), - "email" : getEmail(), - "createdDate" : dateFormat( getCreatedDate(), "long" ), - "modifiedDate" : dateFormat( getModifiedDate(), "long" ) + "id" : getID(), + "username" : getUsername(), + "email" : getEmail(), + "createdDate" : dateFormat( getCreatedDate(), "long" ), + "updatedDate" : dateFormat( getUpdatedDate(), "long" ) }; } diff --git a/modules_app/api/modules_app/v4/models/UserService.cfc b/modules_app/api/modules_app/v4/models/UserService.cfc index 26d8e31..65d506a 100644 --- a/modules_app/api/modules_app/v4/models/UserService.cfc +++ b/modules_app/api/modules_app/v4/models/UserService.cfc @@ -30,13 +30,8 @@ component var q = queryExecute( "select * from users where id = :userID", - { - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } } diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index 5b602fc..13b73f5 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -9,12 +9,9 @@ component extends="coldbox.system.RestHandler" { this.prehandler_only = "show,delete,update"; any function preHandler( event, rc, prc, action, eventArguments ){ - try{ - validateOrFail( - target = rc, - constraints = { rantID : { required : true, type : "numeric" } } - ); - } catch( any e ){ + try { + validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); + } catch ( any e ) { arguments.exception = e; this.onValidationException( argumentCollection = arguments ); } @@ -24,9 +21,7 @@ component extends="coldbox.system.RestHandler" { * Returns a list of Rants */ any function index( event, rc, prc ){ - prc.response.setData( - rantService.list().map( ( rant ) => rant.getMemento() ) - ); + prc.response.setData( rantService.list().map( ( rant ) => rant.getMemento() ) ); } /** @@ -34,9 +29,7 @@ component extends="coldbox.system.RestHandler" { * */ function show( event, rc, prc ){ - prc.response.setData( - rantService.getOrFail( rc.rantID ).getMemento() - ); + prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); } /** @@ -44,9 +37,7 @@ component extends="coldbox.system.RestHandler" { * */ function delete( event, rc, prc ){ - rantService - .getOrFail( rc.rantID ) - .delete(); + rantService.getOrFail( rc.rantID ).delete(); prc.response.addMessage( "Rant deleted" ); } @@ -60,9 +51,7 @@ component extends="coldbox.system.RestHandler" { .validateOrFail() .save(); - prc.response - .setData( { "rantID" : result.getID() } ) - .addMessage( "Rant created" ); + prc.response.setData( { "rantID" : result.getID() } ).addMessage( "Rant created" ); } /** @@ -72,7 +61,7 @@ component extends="coldbox.system.RestHandler" { function update( event, rc, prc ){ rantService .getOrFail( rc.rantID ) - .populate( memento=rc, exclude="id" ) + .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); diff --git a/modules_app/api/modules_app/v5/models/BaseEntity.cfc b/modules_app/api/modules_app/v5/models/BaseEntity.cfc index f76b79f..55f359e 100644 --- a/modules_app/api/modules_app/v5/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v5/models/BaseEntity.cfc @@ -11,9 +11,9 @@ component accessors="true" { property name="entityService"; // DI Injection - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; - property name="coldbox" inject="coldbox"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + property name="coldbox" inject="coldbox"; // Basic memento settings this.memento = { @@ -31,18 +31,18 @@ component accessors="true" { "entityService" ], // A struct of defaults for properties/relationships if they are null - defaults : {}, + defaults : {}, // A struct of mapping functions for properties/relationships that can transform them - mappers : {} + mappers : {} } /** * Initialize Entity - stores information needed * - * @pk The name of the primary key field in the entity - * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @pk The name of the primary key field in the entity + * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards * @serviceName The name of the service that manages the entity - * @moduleName The name of the module for the objects + * @moduleName The name of the module for the objects */ function init( pk = "id", @@ -82,19 +82,19 @@ component accessors="true" { /** * Populate a model object from the request Collection or a passed in memento structure * - * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. - * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object - * @include A list of keys to include in the population - * @exclude A list of keys to exclude in the population - * @ignoreEmpty Ignore empty values on populations, great for ORM population - * @nullEmptyInclude A list of keys to NULL when empty - * @nullEmptyExclude A list of keys to NOT NULL when empty + * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. + * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object + * @include A list of keys to include in the population + * @exclude A list of keys to exclude in the population + * @ignoreEmpty Ignore empty values on populations, great for ORM population + * @nullEmptyInclude A list of keys to NULL when empty + * @nullEmptyExclude A list of keys to NOT NULL when empty * @composeRelationships Automatically attempt to compose relationships from memento - * @memento A structure to populate the model, if not passed it defaults to the request collection - * @jsonstring If you pass a json string, we will populate your model with it - * @xml If you pass an xml string, we will populate your model with it - * @qry If you pass a query, we will populate your model with it - * @rowNumber The row of the qry parameter to populate your model with + * @memento A structure to populate the model, if not passed it defaults to the request collection + * @jsonstring If you pass a json string, we will populate your model with it + * @xml If you pass an xml string, we will populate your model with it + * @qry If you pass a query, we will populate your model with it + * @rowNumber The row of the qry parameter to populate your model with */ function populate( struct memento = coldbox @@ -143,7 +143,7 @@ component accessors="true" { arguments.target = this; return wirebox .getInstance( "ValidationManager@cbvalidation" ) - .validateOrFail( argumentCollection=arguments ); + .validateOrFail( argumentCollection = arguments ); } /** @@ -164,4 +164,4 @@ component accessors="true" { return variables.entityService.delete( this.getID() ); } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v5/models/BaseService.cfc b/modules_app/api/modules_app/v5/models/BaseService.cfc index 42e42ff..9cc0387 100644 --- a/modules_app/api/modules_app/v5/models/BaseService.cfc +++ b/modules_app/api/modules_app/v5/models/BaseService.cfc @@ -4,8 +4,8 @@ component accessors="true" { // DI - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; // Properties property name="entityName"; @@ -49,10 +49,7 @@ component accessors="true" { */ function new( struct data = {} ){ var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); - return populator.populateFromStruct( - target = wireBox.getInstance( modelName ), - memento = arguments.data - ); + return populator.populateFromStruct( target = wireBox.getInstance( modelName ), memento = arguments.data ); } /** @@ -65,12 +62,7 @@ component accessors="true" { queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { - id : { - value : arguments[ 1 ], - cfsqltype : "cf_sql_numeric" - } - } + { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } ).len() ) } @@ -79,31 +71,27 @@ component accessors="true" { * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * * @return Returns true if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( - type = "EntityNotFound", - message = "#entityName# Not Found" - ); + throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } /** * Query and load an entity if possible, else throw an error * * @return Returns the Entity if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( !maybeEntity.isLoaded() ) { - throw( - type = "EntityNotFound", - message = "#getEntityName()# Not Found" - ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } diff --git a/modules_app/api/modules_app/v5/models/Rant.cfc b/modules_app/api/modules_app/v5/models/Rant.cfc index e0c1ad1..1b13af9 100644 --- a/modules_app/api/modules_app/v5/models/Rant.cfc +++ b/modules_app/api/modules_app/v5/models/Rant.cfc @@ -7,21 +7,21 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="userService" inject="UserService@v5"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; + property name="userID" type="string"; // Validation Constraints this.constraints = { body : { required : true }, userID : { - required : true, - type : "numeric", - udf : ( value, target ) => { - if( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false - return userService.exists( arguments.value ); + required : true, + type : "numeric", + udf : ( value, target ) => { + if ( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + return userService.exists( arguments.value ); }, udfMessage : "User ({rejectedValue}) not found" } @@ -42,4 +42,4 @@ component extends="v5.models.BaseEntity" accessors="true" { return userService.get( getUserID() ); } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index 8f59a44..86cdd56 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -24,15 +24,12 @@ component return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new(), rant ); + return populator.populateFromStruct( new (), rant ); } ); } function listArray(){ - return queryExecute( - "select * from rants ORDER BY createdDate DESC", - {} - ).reduce( ( result, row ) => { + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); @@ -42,25 +39,15 @@ component return queryExecute( "select * from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -69,7 +56,7 @@ component function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "insert into rants @@ -77,24 +64,24 @@ component body = :body, userID = :userID, createdDate = :createdDate, - modifiedDate = :modifiedDate + updatedDate = :updatedDate ", { body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, userID : { - value : "#arguments.rant.getuserID()#", - cfsqltype : "cf_sql_numeric" + value : "#arguments.rant.getuserID()#", + cfsqltype : "cf_sql_numeric" }, createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" + value : "#arguments.rant.getCreatedDate()#", + cfsqltype : "cf_sql_timestamp" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -105,26 +92,26 @@ component function update( required Rant rant ){ var now = now(); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "update rants set body = :body, - modifiedDate = :modifiedDate + updatedDate = :updatedDate where id = :rantID ", { rantID : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" + value : "#arguments.rant.getID()#", + cfsqltype : "cf_sql_integer" }, body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } diff --git a/modules_app/api/modules_app/v5/models/User.cfc b/modules_app/api/modules_app/v5/models/User.cfc index bd7495a..2b3ac93 100644 --- a/modules_app/api/modules_app/v5/models/User.cfc +++ b/modules_app/api/modules_app/v5/models/User.cfc @@ -4,12 +4,12 @@ component extends="v5.models.BaseEntity" accessors="true" { // Properties - property name="id" type="string"; - property name="username" type="string"; - property name="email" type="string"; - property name="password" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; /** @@ -20,4 +20,4 @@ component extends="v5.models.BaseEntity" accessors="true" { return this; } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v5/models/UserService.cfc b/modules_app/api/modules_app/v5/models/UserService.cfc index 2e5c166..138757a 100644 --- a/modules_app/api/modules_app/v5/models/UserService.cfc +++ b/modules_app/api/modules_app/v5/models/UserService.cfc @@ -24,13 +24,8 @@ component var q = queryExecute( "select * from users where id = :userID", - { - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } } diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index 9d94708..df60616 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -8,56 +8,50 @@ component extends="coldbox.system.RestHandler" { property name="userService" inject="UserService@v6"; /** - * @x-route (GET) /api/v6/rants * * Returns a list of Rants * + * @x-route (GET) /api/v6/rants * @response-200 ~api-v6/Rants/index/responses.json##200 */ any function index( event, rc, prc ) cache=true cacheTimeout=60{ - prc.response.setData( - rantService.list().map( ( rant ) => rant.getMemento() ) - ); + prc.response.setData( rantService.list().map( ( rant ) => rant.getMemento() ) ); } /** - * @x-route (GET) /api/v6/rants/:rantID * * Display a single Rant. * + * @x-route (GET) /api/v6/rants/:rantID * @x-parameters ~api-v6/Rants/show/parameters.json##parameters * @response-200 ~api-v6/Rants/show/responses.json##200 * @response-404 ~_responses/rant.404.json */ function show( event, rc, prc ) cache=true cacheTimeout=60{ - prc.response.setData( - rantService.getOrFail( rc.rantID ).getMemento() - ); + prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); } /** - * @x-route (DELETE) /api/v6/rants/:rantID * * Delete a single Rant. * + * @x-route (DELETE) /api/v6/rants/:rantID * @x-parameters ~api-v6/Rants/delete/parameters.json##parameters * @response-200 ~api-v6/Rants/delete/responses.json##200 * @response-404 ~_responses/rant.404.json */ function delete( event, rc, prc ){ - rantService - .getOrFail( rc.rantID ) - .delete(); + rantService.getOrFail( rc.rantID ).delete(); prc.response.addMessage( "Rant deleted" ); } /** - * @x-route (POST) /api/v1/rants * * Creates a new Rant. * - * @requestBody ~api-v6/Rants/create/requestBody.json + * @x-route (POST) /api/v1/rants + * @requestBody ~api-v6/Rants/create/requestBody.json * @response-200 ~api-v6/Rants/create/responses.json##200 * @response-400 ~api-v6/Rants/create/responses.json##400 */ @@ -67,26 +61,24 @@ component extends="coldbox.system.RestHandler" { .validateOrFail() .save(); - prc.response - .setData( { "rantID" : result.getID() } ) - .addMessage( "Rant created" ); + prc.response.setData( { "rantID" : result.getID() } ).addMessage( "Rant created" ); getCache( "template" ).clearAllEvents(); } /** - * @x-route (PUT) /api/v1/rants/:rantID * * Update an existing Rant. * - * @requestBody ~api-v6/Rants/update/requestBody.json + * @x-route (PUT) /api/v1/rants/:rantID + * @requestBody ~api-v6/Rants/update/requestBody.json * @response-200 ~api-v6/Rants/update/responses.json##200 * @response-400 ~api-v6/Rants/update/responses.json##400 */ function update( event, rc, prc ){ rantService .getOrFail( rc.rantID ) - .populate( memento=rc, exclude="id" ) + .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); @@ -95,4 +87,4 @@ component extends="coldbox.system.RestHandler" { getCache( "template" ).clearAllEvents(); } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v6/models/BaseEntity.cfc b/modules_app/api/modules_app/v6/models/BaseEntity.cfc index f76b79f..55f359e 100644 --- a/modules_app/api/modules_app/v6/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v6/models/BaseEntity.cfc @@ -11,9 +11,9 @@ component accessors="true" { property name="entityService"; // DI Injection - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; - property name="coldbox" inject="coldbox"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; + property name="coldbox" inject="coldbox"; // Basic memento settings this.memento = { @@ -31,18 +31,18 @@ component accessors="true" { "entityService" ], // A struct of defaults for properties/relationships if they are null - defaults : {}, + defaults : {}, // A struct of mapping functions for properties/relationships that can transform them - mappers : {} + mappers : {} } /** * Initialize Entity - stores information needed * - * @pk The name of the primary key field in the entity - * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @pk The name of the primary key field in the entity + * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards * @serviceName The name of the service that manages the entity - * @moduleName The name of the module for the objects + * @moduleName The name of the module for the objects */ function init( pk = "id", @@ -82,19 +82,19 @@ component accessors="true" { /** * Populate a model object from the request Collection or a passed in memento structure * - * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. - * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object - * @include A list of keys to include in the population - * @exclude A list of keys to exclude in the population - * @ignoreEmpty Ignore empty values on populations, great for ORM population - * @nullEmptyInclude A list of keys to NULL when empty - * @nullEmptyExclude A list of keys to NOT NULL when empty + * @scope Use scope injection instead of setters population. Ex: scope=variables.instance. + * @trustedSetter If set to true, the setter method will be called even if it does not exist in the object + * @include A list of keys to include in the population + * @exclude A list of keys to exclude in the population + * @ignoreEmpty Ignore empty values on populations, great for ORM population + * @nullEmptyInclude A list of keys to NULL when empty + * @nullEmptyExclude A list of keys to NOT NULL when empty * @composeRelationships Automatically attempt to compose relationships from memento - * @memento A structure to populate the model, if not passed it defaults to the request collection - * @jsonstring If you pass a json string, we will populate your model with it - * @xml If you pass an xml string, we will populate your model with it - * @qry If you pass a query, we will populate your model with it - * @rowNumber The row of the qry parameter to populate your model with + * @memento A structure to populate the model, if not passed it defaults to the request collection + * @jsonstring If you pass a json string, we will populate your model with it + * @xml If you pass an xml string, we will populate your model with it + * @qry If you pass a query, we will populate your model with it + * @rowNumber The row of the qry parameter to populate your model with */ function populate( struct memento = coldbox @@ -143,7 +143,7 @@ component accessors="true" { arguments.target = this; return wirebox .getInstance( "ValidationManager@cbvalidation" ) - .validateOrFail( argumentCollection=arguments ); + .validateOrFail( argumentCollection = arguments ); } /** @@ -164,4 +164,4 @@ component accessors="true" { return variables.entityService.delete( this.getID() ); } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v6/models/BaseService.cfc b/modules_app/api/modules_app/v6/models/BaseService.cfc index 42e42ff..9cc0387 100644 --- a/modules_app/api/modules_app/v6/models/BaseService.cfc +++ b/modules_app/api/modules_app/v6/models/BaseService.cfc @@ -4,8 +4,8 @@ component accessors="true" { // DI - property name="wirebox" inject="wirebox"; - property name="populator" inject="wirebox:populator"; + property name="wirebox" inject="wirebox"; + property name="populator" inject="wirebox:populator"; // Properties property name="entityName"; @@ -49,10 +49,7 @@ component accessors="true" { */ function new( struct data = {} ){ var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); - return populator.populateFromStruct( - target = wireBox.getInstance( modelName ), - memento = arguments.data - ); + return populator.populateFromStruct( target = wireBox.getInstance( modelName ), memento = arguments.data ); } /** @@ -65,12 +62,7 @@ component accessors="true" { queryExecute( "select id from #getTableName()# where #getPrimaryKey()# = :id", - { - id : { - value : arguments[ 1 ], - cfsqltype : "cf_sql_numeric" - } - } + { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } ).len() ) } @@ -79,31 +71,27 @@ component accessors="true" { * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * * @return Returns true if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function existsOrFail(){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( - type = "EntityNotFound", - message = "#entityName# Not Found" - ); + throw( type = "EntityNotFound", message = "#entityName# Not Found" ); } /** * Query and load an entity if possible, else throw an error * * @return Returns the Entity if there is a row with the matching Primary Key + * * @throws EntityNotFound if the entity is not found */ function getOrFail(){ var maybeEntity = this.get( argumentCollection = arguments ); if ( !maybeEntity.isLoaded() ) { - throw( - type = "EntityNotFound", - message = "#getEntityName()# Not Found" - ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index e0c1ad1..1b13af9 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -7,21 +7,21 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="userService" inject="UserService@v5"; // Properties - property name="id" type="string"; - property name="body" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; - property name="userID" type="string"; + property name="id" type="string"; + property name="body" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; + property name="userID" type="string"; // Validation Constraints this.constraints = { body : { required : true }, userID : { - required : true, - type : "numeric", - udf : ( value, target ) => { - if( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false - return userService.exists( arguments.value ); + required : true, + type : "numeric", + udf : ( value, target ) => { + if ( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + return userService.exists( arguments.value ); }, udfMessage : "User ({rejectedValue}) not found" } @@ -42,4 +42,4 @@ component extends="v5.models.BaseEntity" accessors="true" { return userService.get( getUserID() ); } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index 8f59a44..86cdd56 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -24,15 +24,12 @@ component return this .listArray() .map( function( rant ){ - return populator.populateFromStruct( new(), rant ); + return populator.populateFromStruct( new (), rant ); } ); } function listArray(){ - return queryExecute( - "select * from rants ORDER BY createdDate DESC", - {} - ).reduce( ( result, row ) => { + return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { result.append( row ); return result; }, [] ); @@ -42,25 +39,15 @@ component return queryExecute( "select * from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } function delete( required numeric rantID ){ queryExecute( "delete from rants where id = :rantID", - { - rantID : { - value : "#rantID#", - cfsqltype : "cf_sql_numeric" - } - }, + { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -69,7 +56,7 @@ component function create( required Rant rant ){ var now = now(); arguments.rant.setCreatedDate( now ); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "insert into rants @@ -77,24 +64,24 @@ component body = :body, userID = :userID, createdDate = :createdDate, - modifiedDate = :modifiedDate + updatedDate = :updatedDate ", { body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, userID : { - value : "#arguments.rant.getuserID()#", - cfsqltype : "cf_sql_numeric" + value : "#arguments.rant.getuserID()#", + cfsqltype : "cf_sql_numeric" }, createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" + value : "#arguments.rant.getCreatedDate()#", + cfsqltype : "cf_sql_timestamp" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } @@ -105,26 +92,26 @@ component function update( required Rant rant ){ var now = now(); - arguments.rant.setModifiedDate( now ); + arguments.rant.setUpdatedDate( now ); queryExecute( "update rants set body = :body, - modifiedDate = :modifiedDate + updatedDate = :updatedDate where id = :rantID ", { rantID : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" + value : "#arguments.rant.getID()#", + cfsqltype : "cf_sql_integer" }, body : { - value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + value : "#arguments.rant.getBody()#", + cfsqltype : "cf_sql_longvarchar" }, - modifiedDate : { - value : "#arguments.rant.getModifiedDate()#", - cfsqltype : "cf_sql_timestamp" + updatedDate : { + value : "#arguments.rant.getUpdatedDate()#", + cfsqltype : "cf_sql_timestamp" } }, { result : "local.result" } diff --git a/modules_app/api/modules_app/v6/models/User.cfc b/modules_app/api/modules_app/v6/models/User.cfc index bd7495a..2b3ac93 100644 --- a/modules_app/api/modules_app/v6/models/User.cfc +++ b/modules_app/api/modules_app/v6/models/User.cfc @@ -4,12 +4,12 @@ component extends="v5.models.BaseEntity" accessors="true" { // Properties - property name="id" type="string"; - property name="username" type="string"; - property name="email" type="string"; - property name="password" type="string"; - property name="createdDate" type="date"; - property name="modifiedDate" type="date"; + property name="id" type="string"; + property name="username" type="string"; + property name="email" type="string"; + property name="password" type="string"; + property name="createdDate" type="date"; + property name="updatedDate" type="date"; /** @@ -20,4 +20,4 @@ component extends="v5.models.BaseEntity" accessors="true" { return this; } -} \ No newline at end of file +} diff --git a/modules_app/api/modules_app/v6/models/UserService.cfc b/modules_app/api/modules_app/v6/models/UserService.cfc index 2e5c166..138757a 100644 --- a/modules_app/api/modules_app/v6/models/UserService.cfc +++ b/modules_app/api/modules_app/v6/models/UserService.cfc @@ -24,13 +24,8 @@ component var q = queryExecute( "select * from users where id = :userID", - { - userID : { - value : "#userID#", - cfsqltype : "cf_sql_numeric" - } - } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new() ); + { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } } diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 23e8cbf..9a38f89 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -14,11 +14,6 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v2/rants" ); var returnedJSON = event.getRenderData().data; expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); - // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); - // expect( returnedJSON ).toHaveKey( "error" ); - // expect( returnedJSON ).toHaveKey( "errors" ); - // expect( returnedJSON ).toHaveKeyWithCase( "ERROR" ); - // expect( returnedJSON ).toHaveKeyWithCase( "errors" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); @@ -43,14 +38,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" + "The 'RANTID' has an invalid type, expected type is uuid" ); } ); } ); when( "I pass a valid but non existing rantID", function(){ then( "I will get a 404 error", function(){ - var rantID = "1" + var rantID = createUUID(); var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -65,8 +60,8 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid and existing rantID", function(){ then( "I will get a single Rant returned", function(){ - var rantID = 7; - var event = get( "/api/v2/rants/#rantID#" ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v2/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -74,7 +69,7 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); - expect( returnedJSON.data.id ).toBe( 7 ); + expect( returnedJSON.data.id ).toBe( testRantId ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -83,7 +78,6 @@ component extends="tests.resources.BaseTest" { } ); } ); - story( "Create a Rant", function(){ given( "I make a get call to /api/v2/rants/create", function(){ when( "Using a get method", function(){ @@ -139,14 +133,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" + "The 'USERID' has an invalid type, expected type is uuid" ); } ); } ); when( "Including no body param", function(){ then( "I will get a 412 error", function(){ - var event = post( "/api/v2/rants/create", { "userID" : "5" } ); + var event = post( "/api/v2/rants/create", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -160,7 +154,7 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 412 error", function(){ - var event = post( "/api/v2/rants/create", { "userID" : "5", "body" : "" } ); + var event = post( "/api/v2/rants/create", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -174,7 +168,10 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var event = post( "/api/v2/rants/create", { "body" : "xsxswxws", "userID" : "1" } ); + var event = post( + "/api/v2/rants/create", + { "body" : "xsxswxws", "userID" : createUUID() } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -188,7 +185,11 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID", function(){ then( "I will get a successful query result with a generatedKey", function(){ - var event = post( "/api/v2/rants/create", { "body" : "xsxswxws", "userID" : "5" } ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( + "/api/v2/rants/create", + { "body" : "xsxswxws", "userID" : "#testUserId#" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -206,14 +207,15 @@ component extends="tests.resources.BaseTest" { } ); } ); - - story( "Update a Rant", function(){ + beforeEach( function( currentSpec ){ + testRant = queryExecute( "select id,userId from rants limit 1" ); + } ); + given( "I make a get call to /api/v2/rants/:rantID/save", function(){ - xwhen( "Using a get method", function(){ + when( "Using a get method", function(){ then( "I will get a 412 error", function(){ - var rantID = "1"; - var event = get( "/api/v2/rants/#rantID#/save" ); + var event = get( "/api/v2/rants/#testRant.id#/save" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -221,14 +223,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (update): GET" ); + expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (save): GET" ); } ); } ); when( "Including no userID param", function(){ then( "I will get a 412 error", function(){ - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", {} ); + var event = put( "/api/v2/rants/#testRant.id#/save", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -242,8 +243,7 @@ component extends="tests.resources.BaseTest" { when( "Including an empty userID param", function(){ then( "I will get a 412 error", function(){ - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "" } ); + var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -257,8 +257,8 @@ component extends="tests.resources.BaseTest" { when( "Including a non numeric userID param", function(){ then( "I will get a 412 error", function(){ - var rantID = "7"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "abc" } ); + var rantID = createUUID(); + var event = put( "/api/v2/rants/#rantID#/save", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -267,16 +267,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'USERID' has an invalid type, expected type is numeric" + "The 'USERID' has an invalid type, expected type is uuid" ); } ); } ); - when( "Including no body param", function(){ then( "I will get a 412 error", function(){ - var rantID = "1"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1" } ); + var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -290,8 +288,10 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 412 error", function(){ - var rantID = "1"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1", "body" : "" } ); + var event = put( + "/api/v2/rants/#testRant.id#/save", + { "userID" : createUUID(), "body" : "" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -303,10 +303,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ + when( "Including a non UUID rantID param", function(){ then( "I will get a 412 error", function(){ - var rantID = "abc"; - var event = post( "/api/v2/rants/#rantID#/save", { "userID" : "1", "body" : "abc" } ); + var event = put( + "/api/v2/rants/abcdddd/save", + { "userID" : createUUID(), "body" : "abc" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -315,17 +317,16 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" + "The 'RANTID' has an invalid type, expected type is uuid" ); } ); } ); when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var rantID = "7"; - var event = post( - "/api/v2/rants/#rantID#/save", - { "body" : "xsxswxws", "userID" : "1" } + var event = put( + "/api/v2/rants/#testRant.id#/save", + { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -340,10 +341,9 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = "1"; - var event = post( - "/api/v2/rants/#rantID#/save", - { "userID" : "5", "body" : "xsxswxws" } + var event = put( + "/api/v2/rants/#createUUID()#/save", + { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -356,16 +356,14 @@ component extends="tests.resources.BaseTest" { } ); } ); - - - - when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var rantID = "7"; - var event = post( - "/api/v2/rants/#rantID#/save", - { "body" : "xsxswxws", "userID" : "5" } + var event = put( + "/api/v2/rants/#testRant.id#/save", + { + "body" : "Updated by my magic integration test", + "userID" : testRant.userId + } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -381,7 +379,6 @@ component extends="tests.resources.BaseTest" { } ); } ); - story( "Delete a Rant", function(){ given( "I make a get call to /api/v2/rants/:rantID/delete", function(){ when( "Using a get method", function(){ @@ -459,14 +456,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( - "The 'RANTID' has an invalid type, expected type is numeric" + "The 'RANTID' has an invalid type, expected type is uuid" ); } ); } ); when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = 1; + var rantID = createUUID(); var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); @@ -482,25 +479,22 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ - var event = post( - "/api/v2/rants/create", - { "body" : "New Rant Created to Delete", "userID" : "5" } - ); - var returnedJSON = event.getRenderData().data; + var testUserId = queryExecute( "select id from users limit 1" ).id; + var testRantId = getInstance( "RantService@v1" ).create( + "my integration test", + testUserId + ).generatedKey; - setup(); - var rantID = returnedJSON.data.rantID; - var event2 = delete( "/api/v2/rants/#rantID#/delete" ); - - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + var event = delete( "/api/v2/rants/#testRantID#/delete" ); + var returnedJSON = event.getRenderData().data; + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 5101841..08cab57 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -1,17 +1,17 @@ -component extends="tests.resources.BaseTest" { +component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V3 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V3 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v3/rants", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v3/rants" ); + scenario( "Get a list of Rants", function(){ + given( "I make a get call to /api/v3/rants", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v3/rants" ); var returnedJSON = event.getRenderData().data; // expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); @@ -28,12 +28,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v3/rants/:rantID", function() { - when( "I pass an invalid rantID", function() { - then( "I will get a 400 error", function() { - var rantID = "x" - var event = get( "/api/v3/rants/#rantID#" ); + scenario( "Get an individual Rant", function(){ + given( "I make a get call to /api/v3/rants/:rantID", function(){ + when( "I pass an invalid rantID", function(){ + then( "I will get a 400 error", function(){ + var rantID = "x" + var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -44,10 +44,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var rantID = "1" - var event = get( "/api/v3/rants/#rantID#" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1" + var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -59,10 +59,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var rantID = 7; - var event = get( "/api/v3/rants/#rantID#" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var rantID = 7; + var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -80,10 +80,10 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function() { - given( "I make a post call to /api/v3/rants", function() { - when( "Using a get method", function() { - then( "I will hit the index action instead of the create action", function() { + scenario( "Create a Rant", function(){ + given( "I make a post call to /api/v3/rants", function(){ + when( "Using a get method", function(){ + then( "I will hit the index action instead of the create action", function(){ var event = get( "/api/v3/rants" ); expect( event.getCurrentAction() ).toBe( "index", @@ -92,9 +92,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v3/rants", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v3/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -105,9 +105,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v3/rants", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v3/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -118,9 +118,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v3/rants", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v3/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -131,9 +131,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v3/rants", { "userID": "5" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v3/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -144,9 +144,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v3/rants", { "userID": "5", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v3/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -157,9 +157,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var event = post( "/api/v3/rants", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -172,9 +172,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v3/rants", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -194,12 +194,12 @@ component extends="tests.resources.BaseTest" { - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v3/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Update a Rant", function(){ + given( "I make a get call to /api/v3/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v3/rants/#rantID#" ); + var event = get( "/api/v3/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -207,10 +207,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v3/rants/#rantID#" ); + var event = post( "/api/v3/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -218,10 +218,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v3/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -233,10 +233,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -247,10 +247,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -262,10 +262,10 @@ component extends="tests.resources.BaseTest" { } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "1" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "1"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -276,10 +276,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "1", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "1"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "1", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -290,10 +290,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "1", "body": "abc" } ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -304,10 +304,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var rantID = "7"; + var event = put( "/api/v3/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -319,10 +319,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID": "5", "body": "xsxswxws" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1"; + var event = put( "/api/v3/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -334,10 +334,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ + var rantID = "7"; + var event = put( "/api/v3/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -353,12 +353,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v3/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Delete a Rant", function(){ + given( "I make a get call to /api/v3/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v3/rants/#rantID#" ); + var event = get( "/api/v3/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -366,10 +366,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v3/rants/#rantID#" ); + var event = post( "/api/v3/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -377,10 +377,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a space for rantID param", function() { - then( "I will hit the index action instead of the delete action", function() { + when( "Including a space for rantID param", function(){ + then( "I will hit the index action instead of the delete action", function(){ var rantID = " "; - var event = get( "/api/v3/rants/#rantID#" ); + var event = get( "/api/v3/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "index", "I expect to hit index action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -388,10 +388,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = delete( "/api/v3/rants/#rantID#" ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -402,10 +402,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = 1; - var event = delete( "/api/v3/rants/#rantID#" ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = 1; + var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -417,9 +417,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { - var event = post( "/api/v3/rants", { "body": "New Rant Created to Delete", "userID": "5" } ); + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ + var event = post( + "/api/v3/rants", + { "body" : "New Rant Created to Delete", "userID" : "5" } + ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); setup(); diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 64ecc42..ff79fcc 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -1,19 +1,19 @@ component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V4 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V4 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v4/rants", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v4/rants" ); + scenario( "Get a list of Rants", function(){ + given( "I make a get call to /api/v4/rants", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v4/rants" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -25,12 +25,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v4/rants/:rantID", function() { - when( "I pass an invalid rantID", function() { - then( "I will get a 400 error", function() { - var rantID = "x" - var event = get( "/api/v4/rants/#rantID#" ); + scenario( "Get an individual Rant", function(){ + given( "I make a get call to /api/v4/rants/:rantID", function(){ + when( "I pass an invalid rantID", function(){ + then( "I will get a 400 error", function(){ + var rantID = "x" + var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -41,12 +41,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var rantID = "1" - var event = get( "/api/v4/rants/#rantID#" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1" + var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); @@ -56,10 +56,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var rantID = 7; - var event = get( "/api/v4/rants/#rantID#" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var rantID = 7; + var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -77,10 +77,10 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function() { - given( "I make a post call to /api/v4/rants", function() { - when( "Using a get method", function() { - then( "I will hit the index action instead of the create action", function() { + scenario( "Create a Rant", function(){ + given( "I make a post call to /api/v4/rants", function(){ + when( "Using a get method", function(){ + then( "I will hit the index action instead of the create action", function(){ var event = get( "/api/v4/rants" ); expect( event.getCurrentAction() ).toBe( "index", @@ -89,9 +89,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v4/rants", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v4/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -102,9 +102,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v4/rants", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v4/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -115,9 +115,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v4/rants", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v4/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -128,9 +128,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v4/rants", { "userID": "5" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v4/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -141,9 +141,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v4/rants", { "userID": "5", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v4/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -154,9 +154,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var event = post( "/api/v4/rants", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -167,9 +167,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v4/rants", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -188,12 +188,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v4/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Update a Rant", function(){ + given( "I make a get call to /api/v4/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v4/rants/#rantID#" ); + var event = get( "/api/v4/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -201,10 +201,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v4/rants/#rantID#" ); + var event = post( "/api/v4/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -212,10 +212,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v4/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -226,10 +226,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -240,10 +240,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -255,10 +255,10 @@ component extends="tests.resources.BaseTest" { } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "1" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -269,10 +269,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "1", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "1", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -283,10 +283,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "1", "body": "abc" } ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -297,10 +297,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 404 error", function() { - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 404 error", function(){ + var rantID = "7"; + var event = put( "/api/v4/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -311,10 +311,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = "1"; - var event = put( "/api/v4/rants/#rantID#", { "userID": "5", "body": "xsxswxws" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1"; + var event = put( "/api/v4/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -325,12 +325,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ + var rantID = "7"; + var event = put( "/api/v4/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -345,12 +345,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v4/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Delete a Rant", function(){ + given( "I make a get call to /api/v4/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v4/rants/#rantID#" ); + var event = get( "/api/v4/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -358,10 +358,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v4/rants/#rantID#" ); + var event = post( "/api/v4/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -369,10 +369,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a space for rantID param", function() { - then( "I will hit the index action instead of the delete action", function() { + when( "Including a space for rantID param", function(){ + then( "I will hit the index action instead of the delete action", function(){ var rantID = " "; - var event = get( "/api/v4/rants/#rantID#" ); + var event = get( "/api/v4/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "index", "I expect to hit index action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -380,10 +380,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = delete( "/api/v4/rants/#rantID#" ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -394,10 +394,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = 1; - var event = delete( "/api/v4/rants/#rantID#" ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = 1; + var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -408,9 +408,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { - var event = post( "/api/v4/rants", { "body": "New Rant Created to Delete", "userID": "5" } ); + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ + var event = post( + "/api/v4/rants", + { "body" : "New Rant Created to Delete", "userID" : "5" } + ); var returnedJSON = event.getRenderData().data; setup(); var rantID = returnedJSON.data.rantID; diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 22958fd..560c8bb 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -1,19 +1,19 @@ component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V5 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V5 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v5/rants", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v5/rants" ); + scenario( "Get a list of Rants", function(){ + given( "I make a get call to /api/v5/rants", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v5/rants" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -25,12 +25,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v5/rants/:rantID", function() { - when( "I pass an invalid rantID", function() { - then( "I will get a 400 error", function() { - var rantID = "x" - var event = get( "/api/v5/rants/#rantID#" ); + scenario( "Get an individual Rant", function(){ + given( "I make a get call to /api/v5/rants/:rantID", function(){ + when( "I pass an invalid rantID", function(){ + then( "I will get a 400 error", function(){ + var rantID = "x" + var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -41,12 +41,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var rantID = "1" - var event = get( "/api/v5/rants/#rantID#" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1" + var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); @@ -56,10 +56,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var rantID = 7; - var event = get( "/api/v5/rants/#rantID#" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var rantID = 7; + var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -77,10 +77,10 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function() { - given( "I make a post call to /api/v5/rants", function() { - when( "Using a get method", function() { - then( "I will hit the index action instead of the create action", function() { + scenario( "Create a Rant", function(){ + given( "I make a post call to /api/v5/rants", function(){ + when( "Using a get method", function(){ + then( "I will hit the index action instead of the create action", function(){ var event = get( "/api/v5/rants" ); expect( event.getCurrentAction() ).toBe( "index", @@ -89,9 +89,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -102,9 +102,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -115,9 +115,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -128,9 +128,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", { "userID": "5" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -141,9 +141,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", { "userID": "5", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -154,9 +154,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v5/rants", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -167,9 +167,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v5/rants", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -188,12 +188,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v5/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Update a Rant", function(){ + given( "I make a get call to /api/v5/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v5/rants/#rantID#" ); + var event = get( "/api/v5/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -201,10 +201,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v5/rants/#rantID#" ); + var event = post( "/api/v5/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -212,10 +212,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -226,10 +226,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -241,10 +241,10 @@ component extends="tests.resources.BaseTest" { } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "1" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -255,10 +255,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "1", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "1", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -269,10 +269,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "1", "body": "abc" } ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -283,10 +283,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v5/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -297,10 +297,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = "1"; - var event = put( "/api/v5/rants/#rantID#", { "userID": "5", "body": "xsxswxws" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1"; + var event = put( "/api/v5/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -311,12 +311,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ + var rantID = "7"; + var event = put( "/api/v5/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -331,12 +331,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v5/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Delete a Rant", function(){ + given( "I make a get call to /api/v5/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v5/rants/#rantID#" ); + var event = get( "/api/v5/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -344,10 +344,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v5/rants/#rantID#" ); + var event = post( "/api/v5/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -355,10 +355,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a space for rantID param", function() { - then( "I will hit the index action instead of the delete action", function() { + when( "Including a space for rantID param", function(){ + then( "I will hit the index action instead of the delete action", function(){ var rantID = " "; - var event = get( "/api/v5/rants/#rantID#" ); + var event = get( "/api/v5/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "index", "I expect to hit index action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -366,10 +366,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = delete( "/api/v5/rants/#rantID#" ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -380,10 +380,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = 1; - var event = delete( "/api/v5/rants/#rantID#" ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = 1; + var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -394,9 +394,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { - var event = post( "/api/v5/rants", { "body": "New Rant Created to Delete", "userID": "5" } ); + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ + var event = post( + "/api/v5/rants", + { "body" : "New Rant Created to Delete", "userID" : "5" } + ); var returnedJSON = event.getRenderData().data; setup(); var rantID = returnedJSON.data.rantID; diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 98a15ff..887226f 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -1,19 +1,19 @@ component extends="tests.resources.BaseTest" { - function run() { - describe( "Rants V6 API Handler", function() { - beforeEach( function( currentSpec ) { + function run(){ + describe( "Rants V6 API Handler", function(){ + beforeEach( function( currentSpec ){ // Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST. setup(); } ); - scenario( "Get a list of Rants", function() { - given( "I make a get call to /api/v6/rants", function() { - when( "I have no search filters", function() { - then( "I will get a list of Rants", function() { - var event = get( "/api/v6/rants" ); + scenario( "Get a list of Rants", function(){ + given( "I make a get call to /api/v6/rants", function(){ + when( "I have no search filters", function(){ + then( "I will get a list of Rants", function(){ + var event = get( "/api/v6/rants" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -25,12 +25,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function() { - given( "I make a get call to /api/v6/rants/:rantID", function() { - when( "I pass an invalid rantID", function() { - then( "it will be ignored and get the full listing", function() { - var rantID = "x" - var event = get( "/api/v6/rants/#rantID#" ); + scenario( "Get an individual Rant", function(){ + given( "I make a get call to /api/v6/rants/:rantID", function(){ + when( "I pass an invalid rantID", function(){ + then( "it will be ignored and get the full listing", function(){ + var rantID = "x" + var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatusCode( 200 ); @@ -39,12 +39,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid but non existing rantID", function() { - then( "I will get a 404 error", function() { - var rantID = "1" - var event = get( "/api/v6/rants/#rantID#" ); + when( "I pass a valid but non existing rantID", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1" + var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); @@ -54,10 +54,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid and existing rantID", function() { - then( "I will get a single Rant returned", function() { - var rantID = 7; - var event = get( "/api/v6/rants/#rantID#" ); + when( "I pass a valid and existing rantID", function(){ + then( "I will get a single Rant returned", function(){ + var rantID = 7; + var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -75,10 +75,10 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function() { - given( "I make a post call to /api/v6/rants", function() { - when( "Using a get method", function() { - then( "I will hit the index action instead of the create action", function() { + scenario( "Create a Rant", function(){ + given( "I make a post call to /api/v6/rants", function(){ + when( "Using a get method", function(){ + then( "I will hit the index action instead of the create action", function(){ var event = get( "/api/v6/rants" ); expect( event.getCurrentAction() ).toBe( "index", @@ -87,9 +87,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", {} ); + when( "Including no userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -100,9 +100,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -113,9 +113,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -126,9 +126,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", { "userID": "5" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -139,9 +139,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", { "userID": "5", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -152,9 +152,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 400 error", function() { - var event = post( "/api/v6/rants", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 400 error", function(){ + var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -165,9 +165,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID", function() { - then( "I will get a successful query result with a generatedKey", function() { - var event = post( "/api/v6/rants", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID", function(){ + then( "I will get a successful query result with a generatedKey", function(){ + var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -186,12 +186,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function() { - given( "I make a get call to /api/v6/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Update a Rant", function(){ + given( "I make a get call to /api/v6/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v6/rants/#rantID#" ); + var event = get( "/api/v6/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -199,10 +199,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v6/rants/#rantID#" ); + var event = post( "/api/v6/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the update action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -210,10 +210,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "" } ); + when( "Including an empty userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -224,10 +224,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "abc" } ); + when( "Including a non numeric userID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -239,10 +239,10 @@ component extends="tests.resources.BaseTest" { } ); - when( "Including no body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "1" } ); + when( "Including no body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -253,10 +253,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including an empty body param", function() { - then( "I will get a 400 error", function() { - var rantID = "4"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "1", "body": "" } ); + when( "Including an empty body param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "4"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "1", "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -267,10 +267,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 405 error because we only accept numeric Ids", function() { - var rantID = "abc"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "1", "body": "abc" } ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 405 error because we only accept numeric Ids", function(){ + var rantID = "abc"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 405 ); @@ -278,10 +278,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid userID for a non existing User", function() { - then( "I will get a 400 error", function() { - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "body": "xsxswxws", "userID": "1" } ); + when( "Including valid userID for a non existing User", function(){ + then( "I will get a 400 error", function(){ + var rantID = "7"; + var event = put( "/api/v6/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -292,10 +292,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = "1"; - var event = put( "/api/v6/rants/#rantID#", { "userID": "5", "body": "xsxswxws" } ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = "1"; + var event = put( "/api/v6/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -306,12 +306,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid body and userID and rantID", function() { - then( "I will update the Rant Successfully", function() { - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "body": "xsxswxws", "userID": "5" } ); + when( "I pass a valid body and userID and rantID", function(){ + then( "I will update the Rant Successfully", function(){ + var rantID = "7"; + var event = put( "/api/v6/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - //debug( returnedJSON ); + // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); @@ -326,12 +326,12 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function() { - given( "I make a get call to /api/v6/rants/:rantID", function() { - when( "Using a get method", function() { - then( "I will hit the show action instead of the update action", function() { + scenario( "Delete a Rant", function(){ + given( "I make a get call to /api/v6/rants/:rantID", function(){ + when( "Using a get method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = get( "/api/v6/rants/#rantID#" ); + var event = get( "/api/v6/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "show", "I expect to hit show action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -339,10 +339,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Using a post method", function() { - then( "I will hit the show action instead of the update action", function() { + when( "Using a post method", function(){ + then( "I will hit the show action instead of the update action", function(){ var rantID = "1"; - var event = post( "/api/v6/rants/#rantID#" ); + var event = post( "/api/v6/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "onInvalidHTTPMethod", "I expect to hit onInvalidHTTPMethod action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -350,10 +350,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a space for rantID param", function() { - then( "I will hit the index action instead of the delete action", function() { + when( "Including a space for rantID param", function(){ + then( "I will hit the index action instead of the delete action", function(){ var rantID = " "; - var event = get( "/api/v6/rants/#rantID#" ); + var event = get( "/api/v6/rants/#rantID#" ); expect( event.getCurrentAction() ).toBe( "index", "I expect to hit index action instead of the delete action due to the VERB, but I actually hit [#event.getCurrentAction()#]" @@ -361,10 +361,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function() { - then( "I will get a 400 error", function() { - var rantID = "abc"; - var event = delete( "/api/v6/rants/#rantID#" ); + when( "Including a non numeric rantID param", function(){ + then( "I will get a 400 error", function(){ + var rantID = "abc"; + var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 405 ); @@ -372,10 +372,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including valid rantID for a non existing Rant", function() { - then( "I will get a 404 error", function() { - var rantID = 1; - var event = delete( "/api/v6/rants/#rantID#" ); + when( "Including valid rantID for a non existing Rant", function(){ + then( "I will get a 404 error", function(){ + var rantID = 1; + var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -386,9 +386,12 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "I pass a valid rantID", function() { - then( "I will delete the rant successfully", function() { - var event = post( "/api/v6/rants", { "body": "New Rant Created to Delete", "userID": "5" } ); + when( "I pass a valid rantID", function(){ + then( "I will delete the rant successfully", function(){ + var event = post( + "/api/v6/rants", + { "body" : "New Rant Created to Delete", "userID" : "5" } + ); var returnedJSON = event.getRenderData().data; setup(); var rantID = returnedJSON.data.rantID; @@ -410,4 +413,4 @@ component extends="tests.resources.BaseTest" { } ); } -} \ No newline at end of file +} From 140202cdbfae39e1f51be989b43010637bfedd86 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 10:29:19 -0500 Subject: [PATCH 42/75] v3 tests finalized --- .../api/modules_app/v1/handlers/Rants.cfc | 58 ++++----- .../api/modules_app/v1/models/RantService.cfc | 6 +- .../api/modules_app/v2/config/Router.cfc | 6 +- .../api/modules_app/v2/handlers/Rants.cfc | 28 ++--- .../api/modules_app/v2/models/RantService.cfc | 6 +- .../api/modules_app/v3/ModuleConfig.cfc | 2 +- .../api/modules_app/v3/config/Router.cfc | 10 +- .../api/modules_app/v3/handlers/Rants.cfc | 41 ++++--- .../api/modules_app/v3/models/BaseService.cfc | 72 +++++++---- .../api/modules_app/v3/models/RantService.cfc | 60 ++++----- .../api/modules_app/v3/models/UserService.cfc | 15 +-- .../api/modules_app/v4/config/Router.cfc | 2 +- .../api/modules_app/v4/handlers/Rants.cfc | 18 +-- .../api/modules_app/v4/models/Rant.cfc | 8 +- .../api/modules_app/v4/models/RantService.cfc | 24 ++-- .../api/modules_app/v4/models/UserService.cfc | 8 +- .../api/modules_app/v5/config/Router.cfc | 2 +- .../api/modules_app/v5/handlers/Rants.cfc | 10 +- .../api/modules_app/v5/models/Rant.cfc | 6 +- .../api/modules_app/v5/models/RantService.cfc | 24 ++-- .../api/modules_app/v5/models/UserService.cfc | 8 +- .../api/modules_app/v6/config/Router.cfc | 2 +- .../api/modules_app/v6/handlers/Rants.cfc | 14 +-- .../api/modules_app/v6/models/Rant.cfc | 6 +- .../api/modules_app/v6/models/RantService.cfc | 24 ++-- .../api/modules_app/v6/models/UserService.cfc | 8 +- tests/specs/integration/api-v2/RantsTest.cfc | 1 - tests/specs/integration/api-v3/RantsTest.cfc | 116 ++++++++---------- 28 files changed, 284 insertions(+), 301 deletions(-) diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index 69d351d..44a2ef6 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -24,19 +24,19 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant */ function view( event, rc, prc ){ - if ( !structKeyExists( rc, "rantID" ) ) { + if ( !structKeyExists( rc, "rantId" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID is required" ); + prc.response.addMessage( "rantId is required" ); return; } - if ( !isValid( "uuid", rc.rantID ) ) { + if ( !isValid( "uuid", rc.rantId ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be a UUID" ); + prc.response.addMessage( "rantId must be a UUID" ); return; } - var rant = rantService.getRant( rc.rantID ); + var rant = rantService.getRant( rc.rantId ); if ( rant.len() ) { prc.response.setData( queryGetRow( rant, 1 ) ); @@ -51,16 +51,16 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant */ function delete( event, rc, prc ){ - if ( !structKeyExists( rc, "rantID" ) ) { + if ( !structKeyExists( rc, "rantId" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID is required" ); - } else if ( !isValid( "UUID", rc.rantID ) ) { + prc.response.addMessage( "rantId is required" ); + } else if ( !isValid( "UUID", rc.rantId ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be a UUID" ); + prc.response.addMessage( "rantId must be a UUID" ); } else { - var result = rantService.delete( rc.rantID ); + var result = rantService.delete( rc.rantId ); if ( result.recordcount > 0 ) { prc.response.addMessage( "Rant deleted" ); } else { @@ -87,28 +87,28 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "Rant body cannot be empty" ); return } - if ( !structKeyExists( rc, "userID" ) ) { + if ( !structKeyExists( rc, "userId" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID is required" ); + prc.response.addMessage( "userId is required" ); return; } - if ( !isValid( "uuid", rc.userID ) ) { + if ( !isValid( "uuid", rc.userId ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID must be a UUID" ); + prc.response.addMessage( "userId must be a UUID" ); return; } - var user = userService.get( rc.userID ) + var user = userService.get( rc.userId ) if ( !user.len() ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); prc.response.addMessage( "User not found" ); return; } - var result = rantService.create( body = rc.body, userID = rc.userID ); + var result = rantService.create( body = rc.body, userId = rc.userId ); if ( result.recordcount ) { - prc.response.setData( { "rantID" : result.generatedKey } ); + prc.response.setData( { "rantId" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); return; } else { @@ -135,38 +135,38 @@ component extends="coldbox.system.RestHandler" { prc.response.addMessage( "Rant body cannot be empty" ); return } - if ( !structKeyExists( rc, "rantID" ) ) { + if ( !structKeyExists( rc, "rantId" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID is required" ); + prc.response.addMessage( "rantId is required" ); return } - if ( !isValid( "uuid", rc.rantID ) ) { + if ( !isValid( "uuid", rc.rantId ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "rantID must be a UUID" ); + prc.response.addMessage( "rantId must be a UUID" ); return } - var rant = rantService.getRant( rc.rantID ) + var rant = rantService.getRant( rc.rantId ) if ( !rant.len() ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); prc.response.addMessage( "Rant not found" ); return; } - if ( !structKeyExists( rc, "userID" ) ) { + if ( !structKeyExists( rc, "userId" ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID is required" ); + prc.response.addMessage( "userId is required" ); return; } - if ( !isValid( "UUID", rc.userID ) ) { + if ( !isValid( "UUID", rc.userId ) ) { prc.response.setError( true ); prc.response.setStatusCode( 412 ); - prc.response.addMessage( "userID must be a UUID" ); + prc.response.addMessage( "userId must be a UUID" ); return; } - var user = userService.get( rc.userID ) + var user = userService.get( rc.userId ) if ( !user.len() ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); @@ -175,8 +175,8 @@ component extends="coldbox.system.RestHandler" { } var result = rantService.update( body = rc.body, - userID = rc.userID, - rantID = rc.rantID + userId = rc.userId, + rantId = rc.rantId ); if ( result.recordcount ) { prc.response.addMessage( "Rant Updated" ); diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index d7e3231..df6dac9 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -32,7 +32,7 @@ component singleton accessors="true" { return local.result; } - function create( required body, required userID ){ + function create( required body, required userId ){ var now = now(); var newId = createUUID(); queryExecute( @@ -40,12 +40,12 @@ component singleton accessors="true" { set id = :rantId, body = :body, - userID = :userID + userId = :userId ", { rantId : newId, body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - userID : arguments.userId + userId : arguments.userId }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v2/config/Router.cfc b/modules_app/api/modules_app/v2/config/Router.cfc index e8d991c..c53a78f 100644 --- a/modules_app/api/modules_app/v2/config/Router.cfc +++ b/modules_app/api/modules_app/v2/config/Router.cfc @@ -3,9 +3,9 @@ component { function configure(){ // CRUD post( "/rants/create", "rants.create" ) - delete( "/rants/:rantID/delete", "rants.delete" ) - put( "/rants/:rantID/save", "rants.save" ) - get( "/rants/:rantID", "rants.view" ) + delete( "/rants/:rantId/delete", "rants.delete" ) + put( "/rants/:rantId/save", "rants.save" ) + get( "/rants/:rantId", "rants.view" ) get( "/rants", "rants.list" ) // Entry Point diff --git a/modules_app/api/modules_app/v2/handlers/Rants.cfc b/modules_app/api/modules_app/v2/handlers/Rants.cfc index 5b13564..7abc971 100644 --- a/modules_app/api/modules_app/v2/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v2/handlers/Rants.cfc @@ -25,13 +25,13 @@ component extends="coldbox.system.RestHandler" { function view( event, rc, prc ){ var validationResults = validate( target = rc, - constraints = { rantID : { required : true, type : "uuid" } } + constraints = { rantId : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; } - var rant = rantService.get( rc.rantID ); + var rant = rantService.get( rc.rantId ); if ( !rant.isEmpty() ) { prc.response.setData( rant ) @@ -46,14 +46,14 @@ component extends="coldbox.system.RestHandler" { function delete( event, rc, prc ){ var validationResults = validate( target = rc, - constraints = { rantID : { required : true, type : "uuid" } } + constraints = { rantId : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; } - var result = rantService.delete( rc.rantID ); + var result = rantService.delete( rc.rantId ); if ( result.recordcount > 0 ) { prc.response.addMessage( "Rant deleted" ); } else { @@ -68,7 +68,7 @@ component extends="coldbox.system.RestHandler" { var validationResults = validate( target = rc, constraints = { - userID : { required : true, type : "uuid" }, + userId : { required : true, type : "uuid" }, body : { required : true } } ); @@ -76,13 +76,13 @@ component extends="coldbox.system.RestHandler" { prc.response.setErrorMessage( validationResults.getAllErrors(), 412 ); return; } - if ( !userService.exists( rc.userID ) ) { + if ( !userService.exists( rc.userId ) ) { prc.response.setErrorMessage( "User not found", 404 ); return; } - var result = rantService.create( body = rc.body, userID = rc.userID ); + var result = rantService.create( body = rc.body, userId = rc.userId ); if ( result.recordcount ) { - prc.response.setData( { "rantID" : result.generatedKey } ); + prc.response.setData( { "rantId" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); return; } else { @@ -98,9 +98,9 @@ component extends="coldbox.system.RestHandler" { var validationResults = validate( target = rc, constraints = { - rantID : { required : true, type : "uuid" }, + rantId : { required : true, type : "uuid" }, body : { required : true }, - userID : { required : true, type : "uuid" } + userId : { required : true, type : "uuid" } } ); if ( validationResults.hasErrors() ) { @@ -108,18 +108,18 @@ component extends="coldbox.system.RestHandler" { return; } - if ( !rantService.exists( rc.rantID ) ) { + if ( !rantService.exists( rc.rantId ) ) { prc.response.setErrorMessage( "Rant not found", 404 ); return; } - if ( !userService.exists( rc.userID ) ) { + if ( !userService.exists( rc.userId ) ) { prc.response.setErrorMessage( "User not found", 404 ); return; } var result = rantService.update( body = rc.body, - userID = rc.userID, - rantID = rc.rantID + userId = rc.userId, + rantId = rc.rantId ); if ( result.recordcount ) { prc.response.addMessage( "Rant Updated" ); diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index bffd7f2..5175fec 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -45,9 +45,9 @@ component singleton accessors="true" { queryExecute( "insert into rants set - id = :rantId, - body = :body, - userId = :userId + id = :rantId, + body = :body, + userId = :userId ", { rantId : newKey, diff --git a/modules_app/api/modules_app/v3/ModuleConfig.cfc b/modules_app/api/modules_app/v3/ModuleConfig.cfc index 721390c..2655f40 100644 --- a/modules_app/api/modules_app/v3/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v3/ModuleConfig.cfc @@ -1,5 +1,5 @@ /** - * Module Config + * v3 Module Config */ component { diff --git a/modules_app/api/modules_app/v3/config/Router.cfc b/modules_app/api/modules_app/v3/config/Router.cfc index da45da4..46f9993 100644 --- a/modules_app/api/modules_app/v3/config/Router.cfc +++ b/modules_app/api/modules_app/v3/config/Router.cfc @@ -1,14 +1,12 @@ component { function configure(){ - resources( - resource = "rants", - parameterName = "rantID", - except = [ "new", "edit" ] - ); + // API Based Resourceful Routes: + // https://coldbox.ortusbooks.com/the-basics/routing/routing-dsl/resourceful-routes#api-resourceful-routes + apiResources( resource = "rants", parameterName = "rantId" ); + // Entry Point route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); } } diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 7d93e10..9328538 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -7,7 +12,6 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v3"; property name="userService" inject="UserService@v3"; - /** * Returns a list of Rants */ @@ -17,42 +21,39 @@ component extends="coldbox.system.RestHandler" { /** * Returns a single Rant - * */ function show( event, rc, prc ){ - validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); - prc.response.setData( rantService.getOrFail( rc.rantID ) ); + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); + prc.response.setData( rantService.getOrFail( rc.rantId ) ); } /** * Deletes a single Rant - * */ function delete( event, rc, prc ){ - var validationResults = validateOrFail( + validateOrFail( target = rc, - constraints = { rantID : { required : true, type : "numeric" } } + constraints = { rantId : { required : true, type : "uuid" } } ); - rantService.existsOrFail( rc.rantID ) - rantService.delete( rc.rantID ); + rantService.existsOrFail( rc.rantId ) + rantService.delete( rc.rantId ); prc.response.addMessage( "Rant deleted" ); } /** * Creates a new Rant - * */ function create( event, rc, prc ){ validateOrFail( target = rc, constraints = { - userID : { required : true, type : "numeric" }, + userId : { required : true, type : "uuid" }, body : { required : true } } ); - userService.existsOrFail( rc.userID ); - var result = rantService.create( body = rc.body, userID = rc.userID ); - prc.response.setData( { "rantID" : result.generatedKey } ); + userService.existsOrFail( rc.userId ); + var result = rantService.create( body = rc.body, userId = rc.userId ); + prc.response.setData( { "rantId" : result.generatedKey } ); prc.response.addMessage( "Rant created" ); } @@ -64,19 +65,19 @@ component extends="coldbox.system.RestHandler" { validateOrFail( target = rc, constraints = { - rantID : { required : true, type : "numeric" }, + rantId : { required : true, type : "uuid" }, body : { required : true }, - userID : { required : true, type : "numeric" } + userId : { required : true, type : "uuid" } } ); - rantService.existsOrFail( rc.rantID ); - userService.existsOrFail( rc.userID ); + rantService.existsOrFail( rc.rantId ); + userService.existsOrFail( rc.userId ); rantService.update( body = rc.body, - userID = rc.userID, - rantID = rc.rantID + userId = rc.userId, + rantId = rc.rantId ); prc.response.addMessage( "Rant Updated" ); diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index 236561f..fdaa86e 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -1,12 +1,11 @@ /** - * I am the Base Service + * I am the Base Service v3 */ component accessors="true" { property name="entityName"; property name="tableName"; property name="primaryKey"; - // property name="parameterName"; property name="serviceName"; property name="moduleName"; @@ -14,37 +13,30 @@ component accessors="true" { entityName, tableName, primaryKey = "id", - // parameterName="", - serviceName = "", + serviceName = "#arguments.entityName#Service", moduleName = "" ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); - // if( arguments.parameterName != "" ){ - // setParameterName( arguments.parameterName ); - // } else { - // setParameterName( arguments.primaryKey ); - // } - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } + setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); } /** - * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load + * Check to see if there is a row with a matching primary key in the database. + * Much faster than a full entity query and object load + * + * @id The primary key id to verify * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists(){ + boolean function exists( required id ){ return booleanFormat( queryExecute( - "select id from #getTableName()# - where #getPrimaryKey()# = :id", - { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } + "select #getPrimaryKey()# from #getTableName()# + where #getPrimaryKey()# = :id", + { id : arguments.id } ).len() ) } @@ -52,30 +44,64 @@ component accessors="true" { /** * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * + * @id The primary key id to verify + * * @return Returns true if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function existsOrFail(){ + boolean function existsOrFail( required id ){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } /** * Query and load an entity if possible, else throw an error * + * @id The primary key id to retrieve + * * @return Returns the Entity if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function getOrFail(){ - var maybeEntity = this.get( argumentCollection = arguments ); + function getOrFail( required id ){ + var maybeEntity = this.get( arguments.id ); if ( maybeEntity.isEmpty() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } + /** + * Try to get an entity from the requested id + * + * @id The primary key id to retrieve + * + * @return Returns the Entity if there is a row with the matching Primary Key or an empty struct if not found + */ + struct function get( required id ){ + return queryExecute( + "select * from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id } + ).reduce( ( result, row ) => row, {} ); + } + + /** + * Base delete entity + */ + function delete( required id ){ + queryExecute( + "delete from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id }, + { result : "local.result" } + ); + return local.result; + } + } diff --git a/modules_app/api/modules_app/v3/models/RantService.cfc b/modules_app/api/modules_app/v3/models/RantService.cfc index 4d3951f..29228cd 100644 --- a/modules_app/api/modules_app/v3/models/RantService.cfc +++ b/modules_app/api/modules_app/v3/models/RantService.cfc @@ -12,57 +12,39 @@ component */ RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", - parameterName = "rantID", - moduleName = "v3" + entityName = "rant", + tableName = "rants", + moduleName = "v3" ) return this; } array function list(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); - } - - struct function get( required numeric rantID ){ return queryExecute( - "select * from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => row, {} ); - } - - function delete( required numeric rantID ){ - queryExecute( - "delete from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, - { result : "local.result" } + "select * from rants ORDER BY createdDate DESC", + {}, + { returnType : "array" } ); - return local.result; } - function create( required body, required numeric userID ){ - var now = now(); + function create( required body, required userId ){ + var now = now(); + var newKey = createUUID(); queryExecute( "insert into rants set - body = :body, - userID = :userID, - createdDate = :createdDate, - updatedDate = :updatedDate + id = :rantId, + body = :body, + userId = :userId ", { - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" }, - createdDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" }, - updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } + rantId : newKey, + body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + userId : arguments.userId }, { result : "local.result" } ); + local.result.generatedKey = newKey; return local.result; } @@ -70,13 +52,13 @@ component var now = now(); queryExecute( "update rants - set - body = :body, - updatedDate = :updatedDate - where id = :rantID + set + body = :body, + updatedDate = :updatedDate + where id = :rantId ", { - rantID : { value : "#rantID#", cfsqltype : "cf_sql_integer" }, + rantId : arguments.rantId, body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } }, diff --git a/modules_app/api/modules_app/v3/models/UserService.cfc b/modules_app/api/modules_app/v3/models/UserService.cfc index ea3d567..884a286 100644 --- a/modules_app/api/modules_app/v3/models/UserService.cfc +++ b/modules_app/api/modules_app/v3/models/UserService.cfc @@ -12,20 +12,11 @@ component */ UserService function init(){ super.init( - entityName = "user", - tableName = "users", - parameterName = "userID", - moduleName = "v3" + entityName = "user", + tableName = "users", + moduleName = "v3" ) return this; } - function get( required numeric userID ){ - return queryExecute( - "select * from users - where id = :userID", - { userID : { value : "#userID#", type : "cf_sql_numeric" } } - ).reduce( ( result, row ) => row, {} ); - } - } diff --git a/modules_app/api/modules_app/v4/config/Router.cfc b/modules_app/api/modules_app/v4/config/Router.cfc index da45da4..f7f9cf1 100644 --- a/modules_app/api/modules_app/v4/config/Router.cfc +++ b/modules_app/api/modules_app/v4/config/Router.cfc @@ -3,7 +3,7 @@ component { function configure(){ resources( resource = "rants", - parameterName = "rantID", + parameterName = "rantId", except = [ "new", "edit" ] ); diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 986afb1..44f385b 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -11,7 +11,7 @@ component extends="coldbox.system.RestHandler" { any function preHandler( event, rc, prc, action, eventArguments ){ try { - validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "numeric" } } ); } catch ( any e ) { arguments.exception = e; this.onValidationException( argumentCollection = arguments ); @@ -29,7 +29,7 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant */ function show( event, rc, prc ){ - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); + prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); } /** @@ -37,8 +37,8 @@ component extends="coldbox.system.RestHandler" { * */ function delete( event, rc, prc ){ - rantService.existsOrFail( rc.rantID ) - rantService.delete( rc.rantID ); + rantService.existsOrFail( rc.rantId ) + rantService.delete( rc.rantId ); prc.response.addMessage( "Rant deleted" ); } @@ -50,14 +50,14 @@ component extends="coldbox.system.RestHandler" { validateOrFail( target = rc, constraints = rant.constraints ); - userService.existsOrFail( rc.userID ); + userService.existsOrFail( rc.userId ); rant.setBody( rc.body ); - rant.setUserID( rc.userID ); + rant.setuserId( rc.userId ); rantService.create( rant ); - prc.response.setData( { "rantID" : rant.getID() } ); + prc.response.setData( { "rantId" : rant.getID() } ); prc.response.addMessage( "Rant created" ); } @@ -69,10 +69,10 @@ component extends="coldbox.system.RestHandler" { validateOrFail( target = rc, constraints = rant.constraints ); - userService.existsOrFail( rc.userID ); + userService.existsOrFail( rc.userId ); rant.setBody( rc.body ); - rant.setUserID( rc.userID ); + rant.setuserId( rc.userId ); rantService.update( rant ); diff --git a/modules_app/api/modules_app/v4/models/Rant.cfc b/modules_app/api/modules_app/v4/models/Rant.cfc index 361d678..9b720d3 100644 --- a/modules_app/api/modules_app/v4/models/Rant.cfc +++ b/modules_app/api/modules_app/v4/models/Rant.cfc @@ -11,12 +11,12 @@ component accessors="true" { property name="body" type="string"; property name="createdDate" type="date"; property name="updatedDate" type="date"; - property name="userID" type="string"; + property name="userId" type="string"; // Validation Constraints this.constraints = { body : { required : true }, - userID : { required : true, type : "numeric" } + userId : { required : true, type : "numeric" } }; /** @@ -30,7 +30,7 @@ component accessors="true" { * getUser */ function getUser(){ - return userService.get( getUserID() ); + return userService.get( getuserId() ); } /** @@ -49,7 +49,7 @@ component accessors="true" { "body" : getBody(), "createdDate" : dateFormat( getCreatedDate(), "long" ), "updatedDate" : dateFormat( getUpdatedDate(), "long" ), - "userId" : getUserID() + "userId" : getuserId() }; } diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index 203324b..75873a2 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -14,7 +14,7 @@ component super.init( entityName = "rant", tableName = "rants", - parameterName = "rantID", + parameterName = "rantId", moduleName = "v4" ) return this; @@ -41,19 +41,19 @@ component }, [] ); } - Rant function get( required numeric rantID ){ + Rant function get( required numeric rantId ){ return queryExecute( "select * from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } - function delete( required numeric rantID ){ + function delete( required numeric rantId ){ queryExecute( "delete from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -68,7 +68,7 @@ component "insert into rants set body = :body, - userID = :userID, + userId = :userId, createdDate = :createdDate, updatedDate = :updatedDate ", @@ -77,8 +77,8 @@ component value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userID : { - value : "#arguments.rant.getuserID()#", + userId : { + value : "#arguments.rant.getuserId()#", cfsqltype : "cf_sql_numeric" }, createdDate : { @@ -104,10 +104,10 @@ component set body = :body, updatedDate = :updatedDate - where id = :rantID + where id = :rantId ", { - rantID : { + rantId : { value : "#arguments.rant.getID()#", cfsqltype : "cf_sql_integer" }, diff --git a/modules_app/api/modules_app/v4/models/UserService.cfc b/modules_app/api/modules_app/v4/models/UserService.cfc index 65d506a..b93347e 100644 --- a/modules_app/api/modules_app/v4/models/UserService.cfc +++ b/modules_app/api/modules_app/v4/models/UserService.cfc @@ -14,7 +14,7 @@ component super.init( entityName = "user", tableName = "users", - parameterName = "userID", + parameterName = "userId", moduleName = "v4" ) return this; @@ -26,11 +26,11 @@ component User function new() provider="User@v4"{ } - User function get( required numeric userID ){ + User function get( required numeric userId ){ var q = queryExecute( "select * from users - where id = :userID", - { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + where id = :userId", + { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } diff --git a/modules_app/api/modules_app/v5/config/Router.cfc b/modules_app/api/modules_app/v5/config/Router.cfc index da45da4..f7f9cf1 100644 --- a/modules_app/api/modules_app/v5/config/Router.cfc +++ b/modules_app/api/modules_app/v5/config/Router.cfc @@ -3,7 +3,7 @@ component { function configure(){ resources( resource = "rants", - parameterName = "rantID", + parameterName = "rantId", except = [ "new", "edit" ] ); diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index 13b73f5..f31a028 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -10,7 +10,7 @@ component extends="coldbox.system.RestHandler" { this.prehandler_only = "show,delete,update"; any function preHandler( event, rc, prc, action, eventArguments ){ try { - validateOrFail( target = rc, constraints = { rantID : { required : true, type : "numeric" } } ); + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "numeric" } } ); } catch ( any e ) { arguments.exception = e; this.onValidationException( argumentCollection = arguments ); @@ -29,7 +29,7 @@ component extends="coldbox.system.RestHandler" { * */ function show( event, rc, prc ){ - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); + prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); } /** @@ -37,7 +37,7 @@ component extends="coldbox.system.RestHandler" { * */ function delete( event, rc, prc ){ - rantService.getOrFail( rc.rantID ).delete(); + rantService.getOrFail( rc.rantId ).delete(); prc.response.addMessage( "Rant deleted" ); } @@ -51,7 +51,7 @@ component extends="coldbox.system.RestHandler" { .validateOrFail() .save(); - prc.response.setData( { "rantID" : result.getID() } ).addMessage( "Rant created" ); + prc.response.setData( { "rantId" : result.getID() } ).addMessage( "Rant created" ); } /** @@ -60,7 +60,7 @@ component extends="coldbox.system.RestHandler" { */ function update( event, rc, prc ){ rantService - .getOrFail( rc.rantID ) + .getOrFail( rc.rantId ) .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); diff --git a/modules_app/api/modules_app/v5/models/Rant.cfc b/modules_app/api/modules_app/v5/models/Rant.cfc index 1b13af9..c74c84a 100644 --- a/modules_app/api/modules_app/v5/models/Rant.cfc +++ b/modules_app/api/modules_app/v5/models/Rant.cfc @@ -11,12 +11,12 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="body" type="string"; property name="createdDate" type="date"; property name="updatedDate" type="date"; - property name="userID" type="string"; + property name="userId" type="string"; // Validation Constraints this.constraints = { body : { required : true }, - userID : { + userId : { required : true, type : "numeric", udf : ( value, target ) => { @@ -39,7 +39,7 @@ component extends="v5.models.BaseEntity" accessors="true" { * getUser */ function getUser(){ - return userService.get( getUserID() ); + return userService.get( getuserId() ); } } diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index 86cdd56..e0b431a 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -14,7 +14,7 @@ component super.init( entityName = "rant", tableName = "rants", - parameterName = "rantID", + parameterName = "rantId", moduleName = "v5" ) return this; @@ -35,19 +35,19 @@ component }, [] ); } - Rant function get( required numeric rantID ){ + Rant function get( required numeric rantId ){ return queryExecute( "select * from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } - function delete( required numeric rantID ){ + function delete( required numeric rantId ){ queryExecute( "delete from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -62,7 +62,7 @@ component "insert into rants set body = :body, - userID = :userID, + userId = :userId, createdDate = :createdDate, updatedDate = :updatedDate ", @@ -71,8 +71,8 @@ component value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userID : { - value : "#arguments.rant.getuserID()#", + userId : { + value : "#arguments.rant.getuserId()#", cfsqltype : "cf_sql_numeric" }, createdDate : { @@ -98,10 +98,10 @@ component set body = :body, updatedDate = :updatedDate - where id = :rantID + where id = :rantId ", { - rantID : { + rantId : { value : "#arguments.rant.getID()#", cfsqltype : "cf_sql_integer" }, diff --git a/modules_app/api/modules_app/v5/models/UserService.cfc b/modules_app/api/modules_app/v5/models/UserService.cfc index 138757a..ad70e01 100644 --- a/modules_app/api/modules_app/v5/models/UserService.cfc +++ b/modules_app/api/modules_app/v5/models/UserService.cfc @@ -14,17 +14,17 @@ component super.init( entityName = "user", tableName = "users", - parameterName = "userID", + parameterName = "userId", moduleName = "v5" ) return this; } - User function get( required numeric userID ){ + User function get( required numeric userId ){ var q = queryExecute( "select * from users - where id = :userID", - { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + where id = :userId", + { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } diff --git a/modules_app/api/modules_app/v6/config/Router.cfc b/modules_app/api/modules_app/v6/config/Router.cfc index acb589f..15761c1 100644 --- a/modules_app/api/modules_app/v6/config/Router.cfc +++ b/modules_app/api/modules_app/v6/config/Router.cfc @@ -7,7 +7,7 @@ component { // Type the ID to numeric resources( resource = "rants", - parameterName = "rantID-numeric", + parameterName = "rantId-numeric", except = [ "new", "edit" ] ) diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index df60616..6423aa4 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -22,26 +22,26 @@ component extends="coldbox.system.RestHandler" { * * Display a single Rant. * - * @x-route (GET) /api/v6/rants/:rantID + * @x-route (GET) /api/v6/rants/:rantId * @x-parameters ~api-v6/Rants/show/parameters.json##parameters * @response-200 ~api-v6/Rants/show/responses.json##200 * @response-404 ~_responses/rant.404.json */ function show( event, rc, prc ) cache=true cacheTimeout=60{ - prc.response.setData( rantService.getOrFail( rc.rantID ).getMemento() ); + prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); } /** * * Delete a single Rant. * - * @x-route (DELETE) /api/v6/rants/:rantID + * @x-route (DELETE) /api/v6/rants/:rantId * @x-parameters ~api-v6/Rants/delete/parameters.json##parameters * @response-200 ~api-v6/Rants/delete/responses.json##200 * @response-404 ~_responses/rant.404.json */ function delete( event, rc, prc ){ - rantService.getOrFail( rc.rantID ).delete(); + rantService.getOrFail( rc.rantId ).delete(); prc.response.addMessage( "Rant deleted" ); } @@ -61,7 +61,7 @@ component extends="coldbox.system.RestHandler" { .validateOrFail() .save(); - prc.response.setData( { "rantID" : result.getID() } ).addMessage( "Rant created" ); + prc.response.setData( { "rantId" : result.getID() } ).addMessage( "Rant created" ); getCache( "template" ).clearAllEvents(); } @@ -70,14 +70,14 @@ component extends="coldbox.system.RestHandler" { * * Update an existing Rant. * - * @x-route (PUT) /api/v1/rants/:rantID + * @x-route (PUT) /api/v1/rants/:rantId * @requestBody ~api-v6/Rants/update/requestBody.json * @response-200 ~api-v6/Rants/update/responses.json##200 * @response-400 ~api-v6/Rants/update/responses.json##400 */ function update( event, rc, prc ){ rantService - .getOrFail( rc.rantID ) + .getOrFail( rc.rantId ) .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index 1b13af9..c74c84a 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -11,12 +11,12 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="body" type="string"; property name="createdDate" type="date"; property name="updatedDate" type="date"; - property name="userID" type="string"; + property name="userId" type="string"; // Validation Constraints this.constraints = { body : { required : true }, - userID : { + userId : { required : true, type : "numeric", udf : ( value, target ) => { @@ -39,7 +39,7 @@ component extends="v5.models.BaseEntity" accessors="true" { * getUser */ function getUser(){ - return userService.get( getUserID() ); + return userService.get( getuserId() ); } } diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index 86cdd56..e0b431a 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -14,7 +14,7 @@ component super.init( entityName = "rant", tableName = "rants", - parameterName = "rantID", + parameterName = "rantId", moduleName = "v5" ) return this; @@ -35,19 +35,19 @@ component }, [] ); } - Rant function get( required numeric rantID ){ + Rant function get( required numeric rantId ){ return queryExecute( "select * from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } } + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } - function delete( required numeric rantID ){ + function delete( required numeric rantId ){ queryExecute( "delete from rants - where id = :rantID", - { rantID : { value : "#rantID#", cfsqltype : "cf_sql_numeric" } }, + where id = :rantId", + { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, { result : "local.result" } ); return local.result; @@ -62,7 +62,7 @@ component "insert into rants set body = :body, - userID = :userID, + userId = :userId, createdDate = :createdDate, updatedDate = :updatedDate ", @@ -71,8 +71,8 @@ component value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userID : { - value : "#arguments.rant.getuserID()#", + userId : { + value : "#arguments.rant.getuserId()#", cfsqltype : "cf_sql_numeric" }, createdDate : { @@ -98,10 +98,10 @@ component set body = :body, updatedDate = :updatedDate - where id = :rantID + where id = :rantId ", { - rantID : { + rantId : { value : "#arguments.rant.getID()#", cfsqltype : "cf_sql_integer" }, diff --git a/modules_app/api/modules_app/v6/models/UserService.cfc b/modules_app/api/modules_app/v6/models/UserService.cfc index 138757a..ad70e01 100644 --- a/modules_app/api/modules_app/v6/models/UserService.cfc +++ b/modules_app/api/modules_app/v6/models/UserService.cfc @@ -14,17 +14,17 @@ component super.init( entityName = "user", tableName = "users", - parameterName = "userID", + parameterName = "userId", moduleName = "v5" ) return this; } - User function get( required numeric userID ){ + User function get( required numeric userId ){ var q = queryExecute( "select * from users - where id = :userID", - { userID : { value : "#userID#", cfsqltype : "cf_sql_numeric" } } + where id = :userId", + { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); } diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 9a38f89..6717cc0 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -197,7 +197,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 08cab57..0ed604a 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -7,17 +7,12 @@ component extends="tests.resources.BaseTest" { setup(); } ); - scenario( "Get a list of Rants", function(){ + story( "Get a list of Rants", function(){ given( "I make a get call to /api/v3/rants", function(){ when( "I have no search filters", function(){ then( "I will get a list of Rants", function(){ var event = get( "/api/v3/rants" ); var returnedJSON = event.getRenderData().data; - // expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); - // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); - // expect( returnedJSON ).toHaveKey( "error" ); - // expect( returnedJSON ).toHaveKey( "errors" ); - // expect( returnedJSON ).toHaveKeyWithCase( "errors" ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( returnedJSON ).toHaveKeyWithCase( "data" ); @@ -28,7 +23,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function(){ + story( "Get an individual Rant", function(){ given( "I make a get call to /api/v3/rants/:rantID", function(){ when( "I pass an invalid rantID", function(){ then( "I will get a 400 error", function(){ @@ -46,7 +41,7 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid but non existing rantID", function(){ then( "I will get a 404 error", function(){ - var rantID = "1" + var rantID = createUUID(); var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -55,14 +50,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); } ); when( "I pass a valid and existing rantID", function(){ then( "I will get a single Rant returned", function(){ - var rantID = 7; - var event = get( "/api/v3/rants/#rantID#" ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v3/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -70,7 +65,7 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); - expect( returnedJSON.data.id ).toBe( 7 ); + expect( returnedJSON.data.id ).toBe( testRantId ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -79,8 +74,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Create a Rant", function(){ + story( "Create a Rant", function(){ given( "I make a post call to /api/v3/rants", function(){ when( "Using a get method", function(){ then( "I will hit the index action instead of the create action", function(){ @@ -118,7 +112,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; @@ -159,7 +153,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : "1" } ); + var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -168,21 +162,21 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); } ); } ); when( "I pass a valid body and userID", function(){ then( "I will get a successful query result with a generatedKey", function(){ - var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : "5" } ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -192,9 +186,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - - scenario( "Update a Rant", function(){ + story( "Update a Rant", function(){ given( "I make a get call to /api/v3/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -220,7 +212,7 @@ component extends="tests.resources.BaseTest" { when( "Including no userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; + var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); @@ -235,7 +227,7 @@ component extends="tests.resources.BaseTest" { when( "Including an empty userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; + var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -247,9 +239,9 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; + var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -261,11 +253,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID" : "1" } ); + var rantID = createUUID(); + var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -278,8 +269,8 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID" : "1", "body" : "" } ); + var rantID = createUUID(); + var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -290,10 +281,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ + when( "Including a non uuid rantID param", function(){ then( "I will get a 400 error", function(){ var rantID = "abc"; - var event = put( "/api/v3/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); + var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID(), "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -306,8 +297,8 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = put( "/api/v3/rants/#testRantId#", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -315,14 +306,13 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); } ); } ); when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = "1"; - var event = put( "/api/v3/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); + var event = put( "/api/v3/rants/#createUUID()#", { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -330,14 +320,14 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); } ); when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var rantID = "7"; - var event = put( "/api/v3/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v3/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -352,8 +342,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Delete a Rant", function(){ + story( "Delete a Rant", function(){ given( "I make a get call to /api/v3/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -388,7 +377,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ + when( "Including a non uuid rantID param", function(){ then( "I will get a 400 error", function(){ var rantID = "abc"; var event = delete( "/api/v3/rants/#rantID#" ); @@ -404,7 +393,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = 1; + var rantID = createUUID(); var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -413,31 +402,28 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON.messages[ 1 ] ).toInclude( "cannot be found" ); + expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); } ); when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ - var event = post( - "/api/v3/rants", - { "body" : "New Rant Created to Delete", "userID" : "5" } - ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var testRantId = getInstance( "RantService@v1" ).create( + "my integration test", + testUserId + ).generatedKey; + + var event = delete( "/api/v3/rants/#testRantID#/delete" ); var returnedJSON = event.getRenderData().data; - debug( returnedJSON ); - setup(); - var rantID = returnedJSON.data.rantID; - var event2 = delete( "/api/v3/rants/#rantID#" ); - - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); From cc6baceff684cca2b34b635cc659dc25ac4270d9 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 16:19:27 -0500 Subject: [PATCH 43/75] v4 finalized --- .../api/modules_app/v3/handlers/Rants.cfc | 5 +- .../api/modules_app/v3/models/BaseService.cfc | 1 + .../api/modules_app/v4/ModuleConfig.cfc | 2 +- .../api/modules_app/v4/config/Router.cfc | 10 +- .../api/modules_app/v4/handlers/Rants.cfc | 28 ++-- .../api/modules_app/v4/models/BaseService.cfc | 80 ++++++++--- .../api/modules_app/v4/models/Rant.cfc | 11 +- .../api/modules_app/v4/models/RantService.cfc | 85 ++++------- .../api/modules_app/v4/models/User.cfc | 10 ++ .../api/modules_app/v4/models/UserService.cfc | 15 +- tests/specs/integration/api-v2/RantsTest.cfc | 4 +- tests/specs/integration/api-v3/RantsTest.cfc | 30 ++-- tests/specs/integration/api-v4/RantsTest.cfc | 136 ++++++++++-------- 13 files changed, 218 insertions(+), 199 deletions(-) diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 9328538..fb90f0a 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -31,10 +31,7 @@ component extends="coldbox.system.RestHandler" { * Deletes a single Rant */ function delete( event, rc, prc ){ - validateOrFail( - target = rc, - constraints = { rantId : { required : true, type : "uuid" } } - ); + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); rantService.existsOrFail( rc.rantId ) rantService.delete( rc.rantId ); prc.response.addMessage( "Rant deleted" ); diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index fdaa86e..a45c613 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -3,6 +3,7 @@ */ component accessors="true" { + // Properties property name="entityName"; property name="tableName"; property name="primaryKey"; diff --git a/modules_app/api/modules_app/v4/ModuleConfig.cfc b/modules_app/api/modules_app/v4/ModuleConfig.cfc index e0eb01d..c6af295 100644 --- a/modules_app/api/modules_app/v4/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v4/ModuleConfig.cfc @@ -1,5 +1,5 @@ /** - * Module Config + * v4 Module Config */ component { diff --git a/modules_app/api/modules_app/v4/config/Router.cfc b/modules_app/api/modules_app/v4/config/Router.cfc index f7f9cf1..46f9993 100644 --- a/modules_app/api/modules_app/v4/config/Router.cfc +++ b/modules_app/api/modules_app/v4/config/Router.cfc @@ -1,14 +1,12 @@ component { function configure(){ - resources( - resource = "rants", - parameterName = "rantId", - except = [ "new", "edit" ] - ); + // API Based Resourceful Routes: + // https://coldbox.ortusbooks.com/the-basics/routing/routing-dsl/resourceful-routes#api-resourceful-routes + apiResources( resource = "rants", parameterName = "rantId" ); + // Entry Point route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); } } diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 44f385b..8daf35a 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -7,17 +12,6 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v4"; property name="userService" inject="UserService@v4"; - this.prehandler_only = "show,delete,update"; - - any function preHandler( event, rc, prc, action, eventArguments ){ - try { - validateOrFail( target = rc, constraints = { rantId : { required : true, type : "numeric" } } ); - } catch ( any e ) { - arguments.exception = e; - this.onValidationException( argumentCollection = arguments ); - } - } - /** * Returns a list of Rants */ @@ -29,15 +23,16 @@ component extends="coldbox.system.RestHandler" { * Returns a single Rant */ function show( event, rc, prc ){ + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); } /** * Deletes a single Rant - * */ function delete( event, rc, prc ){ - rantService.existsOrFail( rc.rantId ) + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); + rantService.existsOrFail( rc.rantId ); rantService.delete( rc.rantId ); prc.response.addMessage( "Rant deleted" ); } @@ -53,11 +48,11 @@ component extends="coldbox.system.RestHandler" { userService.existsOrFail( rc.userId ); rant.setBody( rc.body ); - rant.setuserId( rc.userId ); + rant.setUserId( rc.userId ); rantService.create( rant ); - prc.response.setData( { "rantId" : rant.getID() } ); + prc.response.setData( rant.getMemento() ); prc.response.addMessage( "Rant created" ); } @@ -65,6 +60,8 @@ component extends="coldbox.system.RestHandler" { * Updates an Existing Rant */ function update( event, rc, prc ){ + validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); + var rant = rantService.getOrFail( rc.rantId ); validateOrFail( target = rc, constraints = rant.constraints ); @@ -76,6 +73,7 @@ component extends="coldbox.system.RestHandler" { rantService.update( rant ); + prc.response.setData( rant.getMemento() ); prc.response.addMessage( "Rant Updated" ); } diff --git a/modules_app/api/modules_app/v4/models/BaseService.cfc b/modules_app/api/modules_app/v4/models/BaseService.cfc index e67deca..cd579ba 100644 --- a/modules_app/api/modules_app/v4/models/BaseService.cfc +++ b/modules_app/api/modules_app/v4/models/BaseService.cfc @@ -1,16 +1,16 @@ /** - * I am the Base Service + * I am the Base Service v4 */ component accessors="true" { // DI property name="populator" inject="wirebox:populator"; + property name="wirebox" inject="wirebox"; // Properties property name="entityName"; property name="tableName"; property name="primaryKey"; - // property name="parameterName"; property name="serviceName"; property name="moduleName"; @@ -18,68 +18,102 @@ component accessors="true" { entityName, tableName, primaryKey = "id", - // parameterName="", - serviceName = "", + serviceName = "#arguments.entityName#Service", moduleName = "" ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); - // if( arguments.parameterName != "" ){ - // setParameterName( arguments.parameterName ); - // } else { - // setParameterName( arguments.primaryKey ); - // } - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } + setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); } /** - * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load + * Check to see if there is a row with a matching primary key in the database. + * Much faster than a full entity query and object load + * + * @id The primary key id to verify * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists(){ + boolean function exists( required id ){ return booleanFormat( queryExecute( - "select id from #getTableName()# - where #getPrimaryKey()# = :id", - { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } + "select #getPrimaryKey()# from #getTableName()# + where #getPrimaryKey()# = :id", + { id : arguments.id } ).len() ) } + /** + * Get a new entity object according to entity name + */ + function new(){ + return wirebox.getInstance( "#getEntityname()#@#getModuleName()#" ); + } + /** * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * + * @id The primary key id to verify + * * @return Returns true if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function existsOrFail(){ + boolean function existsOrFail( required id ){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } /** * Query and load an entity if possible, else throw an error * + * @id The primary key id to retrieve + * * @return Returns the Entity if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function getOrFail(){ - var maybeEntity = this.get( argumentCollection = arguments ); + function getOrFail( required id ){ + var maybeEntity = this.get( arguments.id ); if ( !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } + /** + * Try to get an entity from the requested id + * + * @id The primary key id to retrieve + * + * @return Returns the Entity if there is a row with the matching Primary Key or an empty entity if not found + */ + function get( required id ){ + return queryExecute( + "select * from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); + } + + /** + * Base delete entity + */ + function delete( required id ){ + queryExecute( + "delete from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id }, + { result : "local.result" } + ); + return local.result; + } + } diff --git a/modules_app/api/modules_app/v4/models/Rant.cfc b/modules_app/api/modules_app/v4/models/Rant.cfc index 9b720d3..df99bfd 100644 --- a/modules_app/api/modules_app/v4/models/Rant.cfc +++ b/modules_app/api/modules_app/v4/models/Rant.cfc @@ -16,21 +16,24 @@ component accessors="true" { // Validation Constraints this.constraints = { body : { required : true }, - userId : { required : true, type : "numeric" } + userId : { required : true, type : "uuid" } }; /** * Constructor */ Rant function init(){ + var now = now(); + variables.createdDate = now; + variables.updatedDate = now; return this; } /** - * getUser + * get the user */ function getUser(){ - return userService.get( getuserId() ); + return userService.get( getUserId() ); } /** @@ -45,7 +48,7 @@ component accessors="true" { */ function getMemento(){ return { - "id" : getID(), + "rantId" : getId(), "body" : getBody(), "createdDate" : dateFormat( getCreatedDate(), "long" ), "updatedDate" : dateFormat( getUpdatedDate(), "long" ), diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index 75873a2..a11ddf1 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -12,10 +12,9 @@ component */ RantService function init(){ super.init( - entityName = "rant", - tableName = "rants", - parameterName = "rantId", - moduleName = "v4" + entityName = "Rant", + tableName = "rants", + moduleName = "v4" ) return this; } @@ -35,83 +34,48 @@ component } array function listArray(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); - } - - Rant function get( required numeric rantId ){ return queryExecute( - "select * from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - - function delete( required numeric rantId ){ - queryExecute( - "delete from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, - { result : "local.result" } + "select * from rants ORDER BY createdDate DESC", + {}, + { returnType : "array" } ); - return local.result; } function create( required Rant rant ){ var now = now(); - arguments.rant.setCreatedDate( now ); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setId( createUUID() ); queryExecute( "insert into rants - set - body = :body, - userId = :userId, - createdDate = :createdDate, - updatedDate = :updatedDate + set + id = :rantId, + body = :body, + userId = :userId ", { - body : { + rantId : arguments.rant.getId(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userId : { - value : "#arguments.rant.getuserId()#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" - }, - updatedDate : { - value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" - } - }, - { result : "local.result" } + userId : arguments.rant.getuserId() + } ); - arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } function update( required Rant rant ){ - var now = now(); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setUpdatedDate( now() ); queryExecute( "update rants - set - body = :body, - updatedDate = :updatedDate - where id = :rantId + set + body = :body, + updatedDate = :updatedDate + where id = :rantId ", { - rantId : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" - }, - body : { + rantId : arguments.rant.getID(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, @@ -119,10 +83,9 @@ component value : "#arguments.rant.getUpdatedDate()#", cfsqltype : "cf_sql_timestamp" } - }, - { result : "local.result" } + } ); - return local.result; + return arguments.rant; } } diff --git a/modules_app/api/modules_app/v4/models/User.cfc b/modules_app/api/modules_app/v4/models/User.cfc index 00265d9..895090f 100644 --- a/modules_app/api/modules_app/v4/models/User.cfc +++ b/modules_app/api/modules_app/v4/models/User.cfc @@ -11,10 +11,20 @@ component accessors="true" { property name="createdDate" type="date"; property name="updatedDate" type="date"; + // Validation Constraints + this.constraints = { + username : { required : true }, + email : { required : true }, + password : { required : true } + }; + /** * Constructor */ User function init(){ + var now = now(); + variables.createdDate = now; + variables.updatedDate = now; return this; } diff --git a/modules_app/api/modules_app/v4/models/UserService.cfc b/modules_app/api/modules_app/v4/models/UserService.cfc index b93347e..c17d470 100644 --- a/modules_app/api/modules_app/v4/models/UserService.cfc +++ b/modules_app/api/modules_app/v4/models/UserService.cfc @@ -12,10 +12,9 @@ component */ UserService function init(){ super.init( - entityName = "user", - tableName = "users", - parameterName = "userId", - moduleName = "v4" + entityName = "User", + tableName = "users", + moduleName = "v4" ) return this; } @@ -26,12 +25,4 @@ component User function new() provider="User@v4"{ } - User function get( required numeric userId ){ - var q = queryExecute( - "select * from users - where id = :userId", - { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - } diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 6717cc0..72e4883 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -196,7 +196,7 @@ component extends="tests.resources.BaseTest" { expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -479,7 +479,7 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ var testUserId = queryExecute( "select id from users limit 1" ).id; - var testRantId = getInstance( "RantService@v1" ).create( + var testRantId = getInstance( "RantService@v2" ).create( "my integration test", testUserId ).generatedKey; diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 0ed604a..2d5f99b 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -168,7 +168,7 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID", function(){ then( "I will get a successful query result with a generatedKey", function(){ - var testUserId = queryExecute( "select id from users limit 1" ).id; + var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -283,8 +283,11 @@ component extends="tests.resources.BaseTest" { when( "Including a non uuid rantID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "abc"; - var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID(), "body" : "abc" } ); + var rantID = "abc"; + var event = put( + "/api/v3/rants/#rantID#", + { "userID" : createUUID(), "body" : "abc" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -297,8 +300,11 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var testRantId = queryExecute( "select id from rants limit 1" ).id; - var event = put( "/api/v3/rants/#testRantId#", { "body" : "xsxswxws", "userID" : createUUID() } ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = put( + "/api/v3/rants/#testRantId#", + { "body" : "xsxswxws", "userID" : createUUID() } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -312,7 +318,10 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var event = put( "/api/v3/rants/#createUUID()#", { "userID" : createUUID(), "body" : "xsxswxws" } ); + var event = put( + "/api/v3/rants/#createUUID()#", + { "userID" : createUUID(), "body" : "xsxswxws" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -326,8 +335,11 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var testRant = queryExecute( "select id,userId from rants limit 1" ); - var event = put( "/api/v3/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : testRant.userId } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v3/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : testRant.userId } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -409,7 +421,7 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ var testUserId = queryExecute( "select id from users limit 1" ).id; - var testRantId = getInstance( "RantService@v1" ).create( + var testRantId = getInstance( "RantService@v3" ).create( "my integration test", testUserId ).generatedKey; diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index ff79fcc..55ef6ad 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -7,7 +7,7 @@ component extends="tests.resources.BaseTest" { setup(); } ); - scenario( "Get a list of Rants", function(){ + story( "Get a list of Rants", function(){ given( "I make a get call to /api/v4/rants", function(){ when( "I have no search filters", function(){ then( "I will get a list of Rants", function(){ @@ -25,7 +25,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function(){ + story( "Get an individual Rant", function(){ given( "I make a get call to /api/v4/rants/:rantID", function(){ when( "I pass an invalid rantID", function(){ then( "I will get a 400 error", function(){ @@ -43,10 +43,9 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid but non existing rantID", function(){ then( "I will get a 404 error", function(){ - var rantID = "1" + var rantID = createUUID(); var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); @@ -58,16 +57,16 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid and existing rantID", function(){ then( "I will get a single Rant returned", function(){ - var rantID = 7; - var event = get( "/api/v4/rants/#rantID#" ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v4/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatusCode( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); - expect( returnedJSON.data.id ).toBe( 7 ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); + expect( returnedJSON.data.rantId ).toBe( testRantId ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -76,8 +75,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Create a Rant", function(){ + story( "Create a Rant", function(){ given( "I make a post call to /api/v4/rants", function(){ when( "Using a get method", function(){ then( "I will hit the index action instead of the create action", function(){ @@ -115,7 +113,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; @@ -130,7 +128,7 @@ component extends="tests.resources.BaseTest" { when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v4/rants", { "userID" : "5" } ); + var event = post( "/api/v4/rants", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -143,7 +141,7 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v4/rants", { "userID" : "5", "body" : "" } ); + var event = post( "/api/v4/rants", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -156,7 +154,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : "1" } ); + var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -168,16 +166,16 @@ component extends="tests.resources.BaseTest" { } ); when( "I pass a valid body and userID", function(){ - then( "I will get a successful query result with a generatedKey", function(){ - var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : "5" } ); + then( "I will get a successful rant created", function(){ + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -187,8 +185,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Update a Rant", function(){ + story( "Update a Rant", function(){ given( "I make a get call to /api/v4/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -214,8 +211,8 @@ component extends="tests.resources.BaseTest" { when( "Including no userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", {} ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v4/rants/#testRant.id#", {} ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -228,8 +225,8 @@ component extends="tests.resources.BaseTest" { when( "Including an empty userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -240,10 +237,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "abc" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -254,11 +251,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v4/rants/#testRant.id#", { "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -271,8 +267,11 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "1", "body" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v4/rants/#testRant.id#", + { "userID" : testRant.userId, "body" : "" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -283,10 +282,14 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ + when( "Including a non uuid rantID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "abc"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var rantID = "abc"; + var event = put( + "/api/v4/rants/#rantID#", + { "userID" : testRant.userId, "body" : "abc" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -299,8 +302,11 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 404 error", function(){ - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v4/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : createUUID() } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -313,8 +319,11 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = "1"; - var event = put( "/api/v4/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v4/rants/#testRant.id#", + { "userID" : createUUID(), "body" : "xsxswxws" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -327,8 +336,11 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var rantID = "7"; - var event = put( "/api/v4/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v4/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : testRant.userId } + ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -344,8 +356,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Delete a Rant", function(){ + story( "Delete a Rant", function(){ given( "I make a get call to /api/v4/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -380,7 +391,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ + when( "Including a non uuid rantID param", function(){ then( "I will get a 400 error", function(){ var rantID = "abc"; var event = delete( "/api/v4/rants/#rantID#" ); @@ -396,7 +407,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = 1; + var rantID = createUUID(); var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -410,24 +421,25 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ - var event = post( - "/api/v4/rants", - { "body" : "New Rant Created to Delete", "userID" : "5" } - ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var rantService = getInstance( "RantService@v4" ); + var testRant = rantService + .new() + .setId( createUUID() ) + .setBody( "integration testing is lovely!" ) + .setUserId( testUserId ); + rantService.create( testRant ); + + var event = delete( "/api/v4/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - setup(); - var rantID = returnedJSON.data.rantID; - var event2 = delete( "/api/v4/rants/#rantID#" ); - - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); From af989de726e4f4a32360c4af37083b3ae6593404 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 16:21:55 -0500 Subject: [PATCH 44/75] small tweaks for consistency --- modules_app/api/modules_app/v3/handlers/Rants.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index fb90f0a..91b68fa 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -32,7 +32,7 @@ component extends="coldbox.system.RestHandler" { */ function delete( event, rc, prc ){ validateOrFail( target = rc, constraints = { rantId : { required : true, type : "uuid" } } ); - rantService.existsOrFail( rc.rantId ) + rantService.existsOrFail( rc.rantId ); rantService.delete( rc.rantId ); prc.response.addMessage( "Rant deleted" ); } From 3eca956b0e29451744e3a62a4b404dbcc58ff89d Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 17:21:34 -0500 Subject: [PATCH 45/75] v5 almost done --- .../api/modules_app/v4/models/BaseService.cfc | 1 + .../api/modules_app/v5/config/Router.cfc | 10 +- .../api/modules_app/v5/handlers/Rants.cfc | 25 ++--- .../api/modules_app/v5/models/BaseEntity.cfc | 89 ++++++++-------- .../api/modules_app/v5/models/BaseService.cfc | 100 ++++++++++++------ .../api/modules_app/v5/models/Rant.cfc | 18 ++-- .../api/modules_app/v5/models/RantService.cfc | 86 +++++---------- .../api/modules_app/v5/models/User.cfc | 9 +- .../api/modules_app/v5/models/UserService.cfc | 13 +-- 9 files changed, 175 insertions(+), 176 deletions(-) diff --git a/modules_app/api/modules_app/v4/models/BaseService.cfc b/modules_app/api/modules_app/v4/models/BaseService.cfc index cd579ba..1f0fe21 100644 --- a/modules_app/api/modules_app/v4/models/BaseService.cfc +++ b/modules_app/api/modules_app/v4/models/BaseService.cfc @@ -26,6 +26,7 @@ component accessors="true" { setPrimaryKey( arguments.primaryKey ); setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); + return this; } /** diff --git a/modules_app/api/modules_app/v5/config/Router.cfc b/modules_app/api/modules_app/v5/config/Router.cfc index f7f9cf1..46f9993 100644 --- a/modules_app/api/modules_app/v5/config/Router.cfc +++ b/modules_app/api/modules_app/v5/config/Router.cfc @@ -1,14 +1,12 @@ component { function configure(){ - resources( - resource = "rants", - parameterName = "rantId", - except = [ "new", "edit" ] - ); + // API Based Resourceful Routes: + // https://coldbox.ortusbooks.com/the-basics/routing/routing-dsl/resourceful-routes#api-resourceful-routes + apiResources( resource = "rants", parameterName = "rantId" ); + // Entry Point route( "/", "echo.index" ); - route( "/:handler/:action" ).end(); } } diff --git a/modules_app/api/modules_app/v5/handlers/Rants.cfc b/modules_app/api/modules_app/v5/handlers/Rants.cfc index f31a028..7e26cd8 100644 --- a/modules_app/api/modules_app/v5/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v5/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -9,12 +14,7 @@ component extends="coldbox.system.RestHandler" { this.prehandler_only = "show,delete,update"; any function preHandler( event, rc, prc, action, eventArguments ){ - try { - validateOrFail( target = rc, constraints = { rantId : { required : true, type : "numeric" } } ); - } catch ( any e ) { - arguments.exception = e; - this.onValidationException( argumentCollection = arguments ); - } + param rc.rantId = ""; } /** @@ -26,7 +26,6 @@ component extends="coldbox.system.RestHandler" { /** * Returns a single Rant - * */ function show( event, rc, prc ){ prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); @@ -34,11 +33,9 @@ component extends="coldbox.system.RestHandler" { /** * Deletes a single Rant - * */ function delete( event, rc, prc ){ rantService.getOrFail( rc.rantId ).delete(); - prc.response.addMessage( "Rant deleted" ); } @@ -46,12 +43,11 @@ component extends="coldbox.system.RestHandler" { * Creates a new Rant */ function create( event, rc, prc ){ - var result = rantService + var rant = rantService .new( rc ) .validateOrFail() .save(); - - prc.response.setData( { "rantId" : result.getID() } ).addMessage( "Rant created" ); + prc.response.setData( rant.getMemento() ).addMessage( "Rant created" ); } /** @@ -59,13 +55,12 @@ component extends="coldbox.system.RestHandler" { * */ function update( event, rc, prc ){ - rantService + var rant = rantService .getOrFail( rc.rantId ) .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); - - prc.response.addMessage( "Rant Updated" ); + prc.response.setData( rant.getMemento() ).addMessage( "Rant Updated" ); } } diff --git a/modules_app/api/modules_app/v5/models/BaseEntity.cfc b/modules_app/api/modules_app/v5/models/BaseEntity.cfc index 55f359e..1d22dee 100644 --- a/modules_app/api/modules_app/v5/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v5/models/BaseEntity.cfc @@ -1,14 +1,15 @@ /** - * I am the Base Entity + * I am a base entity which exposes some very cool methods to provide fluency and readability + * while still encapsulating them in a service. */ component accessors="true" { - // global properties - property name="pk"; - property name="entityName"; - property name="serviceName"; - property name="moduleName"; - property name="entityService"; + // Entity metadata + service + property name="_primaryKey"; + property name="_entityName"; + property name="_serviceName"; + property name="_moduleName"; + property name="_entityService"; // DI Injection property name="wirebox" inject="wirebox"; @@ -24,11 +25,11 @@ component accessors="true" { // An array of properties/relationships to NEVER include neverInclude : [ "password", - "pk", - "entityName", - "serviceName", - "moduleName", - "entityService" + "_primaryKey", + "_entityName", + "_serviceName", + "_moduleName", + "_entityService" ], // A struct of defaults for properties/relationships if they are null defaults : {}, @@ -39,44 +40,48 @@ component accessors="true" { /** * Initialize Entity - stores information needed * - * @pk The name of the primary key field in the entity + * @primaryKey The name of the primary key field in the entity * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards - * @serviceName The name of the service that manages the entity * @moduleName The name of the module for the objects + * @serviceName The name of the service that manages the entity */ function init( - pk = "id", + primaryKey = "id", entityName = "", - serviceName = "", - moduleName = "" + moduleName = "v5", + serviceName = "#arguments.entityName#Service@#arguments.moduleName#" ){ - setPk( arguments.pk ); - - if ( len( entityName ) ) { - setEntityName( arguments.entityName ); - } + variables._primaryKey = arguments.primaryKey; + variables._entityName = arguments.entityName; + variables._moduleName = arguments.moduleName; + variables._serviceName = arguments.serviceName; - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } - - setModuleName( arguments.moduleName ); - if ( arguments.moduleName != "" ) { - setServiceName( getServiceName() & "@" & arguments.moduleName ); - } + return this; } + /** + * Once this entity is loaded, load up it's companion service + */ function onDIComplete(){ - variables.entityService = wirebox.getInstance( getServiceName() ); + variables._entityService = wirebox.getInstance( getServiceName() ); } /** * Verify if entity is loaded or not */ boolean function isLoaded(){ - return ( !structKeyExists( variables, getPk() ) OR !len( variables[ getPk() ] ) ? false : true ); + return ( + !structKeyExists( variables, variables._primaryKey ) OR !len( variables[ variables._primaryKey ] ) ? false : true + ); + } + + /** + * Get the primary key value of this object. + * + * @return The primary key or an empty value if not set. + */ + function getId(){ + return isLoaded() ? variables[ variables._primaryKey ] : ""; } /** @@ -113,19 +118,19 @@ component accessors="true" { string xml, query qry ){ - arguments[ "model" ] = this; - arguments.target = this; + // Seed the target for population + arguments[ "target" ] = this; // json? - if ( structKeyExists( arguments, "jsonstring" ) ) { + if ( !isNull( arguments.jsonstring ) ) { return variables.populator.populateFromJSON( argumentCollection = arguments ); } // XML - else if ( structKeyExists( arguments, "xml" ) ) { + else if ( !isNull( arguments.xml ) ) { return variables.populator.populateFromXML( argumentCollection = arguments ); } // Query - else if ( structKeyExists( arguments, "qry" ) ) { + else if ( !isNull( arguments.qry ) ) { return variables.populator.populateFromQuery( argumentCollection = arguments ); } // Mementos @@ -151,9 +156,9 @@ component accessors="true" { */ function save(){ if ( isLoaded() ) { - return variables.entityService.update( this ); + return variables._entityService.update( this ); } else { - return variables.entityService.create( this ); + return variables._entityService.create( this ); } } @@ -161,7 +166,7 @@ component accessors="true" { * Delete an entity */ function delete(){ - return variables.entityService.delete( this.getID() ); + return variables._entityService.delete( this.getId() ); } } diff --git a/modules_app/api/modules_app/v5/models/BaseService.cfc b/modules_app/api/modules_app/v5/models/BaseService.cfc index 9cc0387..f41481e 100644 --- a/modules_app/api/modules_app/v5/models/BaseService.cfc +++ b/modules_app/api/modules_app/v5/models/BaseService.cfc @@ -1,5 +1,5 @@ /** - * I am the Base Service + * I am the Base Service v5 */ component accessors="true" { @@ -11,58 +11,60 @@ component accessors="true" { property name="entityName"; property name="tableName"; property name="primaryKey"; - // property name="parameterName"; property name="serviceName"; property name="moduleName"; + /** + * Constructorhonduras + * + * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @tableName The table name this service is bound to + * @primaryKey The primary key to use for operations + * @moduleName The name of the module for the objects + * @serviceName The name of the service that manages the entity + */ function init( entityName, tableName, primaryKey = "id", - // parameterName="", - serviceName = "", - moduleName = "" + moduleName = "v5", + serviceName = "#arguments.entityName#Service@#arguments.moduleName#" ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); - // if( arguments.parameterName != "" ){ - // setParameterName( arguments.parameterName ); - // } else { - // setParameterName( arguments.primaryKey ); - // } - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } + setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); - if ( arguments.moduleName != "" ) { - setServiceName( getServiceName() & "@" & arguments.moduleName ); - } + + return this; } /** - * Return a new Entity, empty or pre-populated with passed in data + * Get a new entity object according to entity name * - * @data Data to populate the new Entity with + * @properties The initial properties to populate the entity with + * + * @return A brand spanking new entity object */ - function new( struct data = {} ){ - var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); - return populator.populateFromStruct( target = wireBox.getInstance( modelName ), memento = arguments.data ); + function new( struct properties = {} ){ + var entity = wirebox.getInstance( "#getEntityname()#@#getModuleName()#" ); + return populator.populateFromStruct( target = entity, memento = arguments.properties ); } /** - * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load + * Check to see if there is a row with a matching primary key in the database. + * Much faster than a full entity query and object load + * + * @id The primary key id to verify * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists(){ + boolean function exists( required id ){ return booleanFormat( queryExecute( - "select id from #getTableName()# - where #getPrimaryKey()# = :id", - { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } + "select #getPrimaryKey()# from #getTableName()# + where #getPrimaryKey()# = :id", + { id : arguments.id } ).len() ) } @@ -70,30 +72,64 @@ component accessors="true" { /** * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * + * @id The primary key id to verify + * * @return Returns true if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function existsOrFail(){ + boolean function existsOrFail( required id ){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } /** * Query and load an entity if possible, else throw an error * + * @id The primary key id to retrieve + * * @return Returns the Entity if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function getOrFail(){ - var maybeEntity = this.get( argumentCollection = arguments ); + function getOrFail( required id ){ + var maybeEntity = this.get( arguments.id ); if ( !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } + /** + * Try to get an entity from the requested id + * + * @id The primary key id to retrieve + * + * @return Returns the Entity if there is a row with the matching Primary Key or an empty entity if not found + */ + function get( required id ){ + return queryExecute( + "select * from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); + } + + /** + * Base delete entity + */ + function delete( required id ){ + queryExecute( + "delete from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id }, + { result : "local.result" } + ); + return local.result; + } + } diff --git a/modules_app/api/modules_app/v5/models/Rant.cfc b/modules_app/api/modules_app/v5/models/Rant.cfc index c74c84a..69d7f97 100644 --- a/modules_app/api/modules_app/v5/models/Rant.cfc +++ b/modules_app/api/modules_app/v5/models/Rant.cfc @@ -18,9 +18,9 @@ component extends="v5.models.BaseEntity" accessors="true" { body : { required : true }, userId : { required : true, - type : "numeric", + type : "uuid", udf : ( value, target ) => { - if ( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + if ( isNull( arguments.value ) || !isValid( "uuid", arguments.value ) ) return false; return userService.exists( arguments.value ); }, udfMessage : "User ({rejectedValue}) not found" @@ -31,15 +31,21 @@ component extends="v5.models.BaseEntity" accessors="true" { * Constructor */ Rant function init(){ - super.init( entityName = "rant", moduleName = "v5" ); - return this; + return super.init( entityName = "rant" ); } /** - * getUser + * Get related user object */ function getUser(){ - return userService.get( getuserId() ); + return userService.get( getUserId() ); + } + + /** + * Does this rant have a user assigned to it already + */ + boolean function hasUser(){ + return !isNull( variables.userId ) && len( variables.userId ); } } diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index e0b431a..8486ce0 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -12,15 +12,14 @@ component */ RantService function init(){ super.init( - entityName = "rant", + entityName = "Rant", tableName = "rants", - parameterName = "rantId", - moduleName = "v5" + parameterName = "rantId" ) return this; } - function list(){ + array function list(){ return this .listArray() .map( function( rant ){ @@ -28,84 +27,49 @@ component } ); } - function listArray(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); - } - - Rant function get( required numeric rantId ){ + array function listArray(){ return queryExecute( - "select * from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - - function delete( required numeric rantId ){ - queryExecute( - "delete from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, - { result : "local.result" } + "select * from rants ORDER BY createdDate DESC", + {}, + { returnType : "array" } ); - return local.result; } function create( required Rant rant ){ var now = now(); - arguments.rant.setCreatedDate( now ); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setId( createUUID() ); queryExecute( "insert into rants - set - body = :body, - userId = :userId, - createdDate = :createdDate, - updatedDate = :updatedDate + set + id = :rantId, + body = :body, + userId = :userId ", { - body : { + rantId : arguments.rant.getId(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userId : { - value : "#arguments.rant.getuserId()#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" - }, - updatedDate : { - value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" - } - }, - { result : "local.result" } + userId : arguments.rant.getuserId() + } ); - arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } function update( required Rant rant ){ - var now = now(); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setUpdatedDate( now() ); queryExecute( "update rants - set - body = :body, - updatedDate = :updatedDate - where id = :rantId + set + body = :body, + updatedDate = :updatedDate + where id = :rantId ", { - rantId : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" - }, - body : { + rantId : arguments.rant.getID(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, @@ -113,10 +77,8 @@ component value : "#arguments.rant.getUpdatedDate()#", cfsqltype : "cf_sql_timestamp" } - }, - { result : "local.result" } + } ); - return arguments.rant; } diff --git a/modules_app/api/modules_app/v5/models/User.cfc b/modules_app/api/modules_app/v5/models/User.cfc index 2b3ac93..0657f7c 100644 --- a/modules_app/api/modules_app/v5/models/User.cfc +++ b/modules_app/api/modules_app/v5/models/User.cfc @@ -11,13 +11,18 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="createdDate" type="date"; property name="updatedDate" type="date"; + // Validation Constraints + this.constraints = { + username : { required : true }, + email : { required : true }, + password : { required : true } + }; /** * Constructor */ User function init(){ - super.init( entityName = "User", moduleName = "v5" ); - return this; + return super.init( entityName = "User" ); } } diff --git a/modules_app/api/modules_app/v5/models/UserService.cfc b/modules_app/api/modules_app/v5/models/UserService.cfc index ad70e01..6c8a8dc 100644 --- a/modules_app/api/modules_app/v5/models/UserService.cfc +++ b/modules_app/api/modules_app/v5/models/UserService.cfc @@ -12,20 +12,11 @@ component */ UserService function init(){ super.init( - entityName = "user", + entityName = "User", tableName = "users", - parameterName = "userId", - moduleName = "v5" + parameterName = "userId" ) return this; } - User function get( required numeric userId ){ - var q = queryExecute( - "select * from users - where id = :userId", - { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - } From 44d07fdf81bbed14e01f8dbf51431d15e6ed4844 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 17:31:40 -0500 Subject: [PATCH 46/75] v5 done --- .../api/modules_app/v5/models/BaseEntity.cfc | 8 +- tests/specs/integration/api-v5/RantsTest.cfc | 110 +++++++++--------- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/modules_app/api/modules_app/v5/models/BaseEntity.cfc b/modules_app/api/modules_app/v5/models/BaseEntity.cfc index 1d22dee..17f1733 100644 --- a/modules_app/api/modules_app/v5/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v5/models/BaseEntity.cfc @@ -51,9 +51,9 @@ component accessors="true" { moduleName = "v5", serviceName = "#arguments.entityName#Service@#arguments.moduleName#" ){ - variables._primaryKey = arguments.primaryKey; - variables._entityName = arguments.entityName; - variables._moduleName = arguments.moduleName; + variables._primaryKey = arguments.primaryKey; + variables._entityName = arguments.entityName; + variables._moduleName = arguments.moduleName; variables._serviceName = arguments.serviceName; return this; @@ -63,7 +63,7 @@ component accessors="true" { * Once this entity is loaded, load up it's companion service */ function onDIComplete(){ - variables._entityService = wirebox.getInstance( getServiceName() ); + variables._entityService = wirebox.getInstance( variables._serviceName ); } /** diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 560c8bb..f0144ed 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -7,7 +7,7 @@ component extends="tests.resources.BaseTest" { setup(); } ); - scenario( "Get a list of Rants", function(){ + story( "Get a list of Rants", function(){ given( "I make a get call to /api/v5/rants", function(){ when( "I have no search filters", function(){ then( "I will get a list of Rants", function(){ @@ -25,16 +25,16 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function(){ + story( "Get an individual Rant", function(){ given( "I make a get call to /api/v5/rants/:rantID", function(){ when( "I pass an invalid rantID", function(){ - then( "I will get a 400 error", function(){ + then( "I will get a 404 error", function(){ var rantID = "x" var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -43,7 +43,7 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid but non existing rantID", function(){ then( "I will get a 404 error", function(){ - var rantID = "1" + var rantID = createUUID(); var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); @@ -58,8 +58,8 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid and existing rantID", function(){ then( "I will get a single Rant returned", function(){ - var rantID = 7; - var event = get( "/api/v5/rants/#rantID#" ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v5/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -67,7 +67,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); - expect( returnedJSON.data.id ).toBe( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -76,8 +75,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Create a Rant", function(){ + story( "Create a Rant", function(){ given( "I make a post call to /api/v5/rants", function(){ when( "Using a get method", function(){ then( "I will hit the index action instead of the create action", function(){ @@ -115,7 +113,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; @@ -156,7 +154,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : "1" } ); + var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -169,15 +167,15 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID", function(){ then( "I will get a successful query result with a generatedKey", function(){ - var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : "5" } ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); + expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -187,8 +185,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Update a Rant", function(){ + story( "Update a Rant", function(){ given( "I make a get call to /api/v5/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -214,8 +211,8 @@ component extends="tests.resources.BaseTest" { when( "Including an empty userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "userID" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -226,10 +223,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "userID" : "abc" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -240,11 +237,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v5/rants/#rantID#", { "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -257,8 +253,8 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v5/rants/#rantID#", { "userID" : "1", "body" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -269,14 +265,14 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ - then( "I will get a 400 error", function(){ + when( "Including a non uuid rantID param", function(){ + then( "I will get a 404 error", function(){ var rantID = "abc"; var event = put( "/api/v5/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -285,8 +281,8 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -313,8 +309,8 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var rantID = "7"; - var event = put( "/api/v5/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -330,8 +326,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - - scenario( "Delete a Rant", function(){ + story( "Delete a Rant", function(){ given( "I make a get call to /api/v5/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -366,14 +361,14 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ - then( "I will get a 400 error", function(){ + when( "Including a non uuid rantID param", function(){ + then( "I will get a 404 error", function(){ var rantID = "abc"; var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatusCode( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -382,7 +377,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = 1; + var rantID = createUUID(); var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -396,24 +391,25 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ - var event = post( - "/api/v5/rants", - { "body" : "New Rant Created to Delete", "userID" : "5" } - ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var rantService = getInstance( "RantService@v4" ); + var testRant = rantService + .new() + .setId( createUUID() ) + .setBody( "integration testing is lovely!" ) + .setUserId( testUserId ); + rantService.create( testRant ); + + var event = delete( "/api/v5/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - setup(); - var rantID = returnedJSON.data.rantID; - var event2 = delete( "/api/v5/rants/#rantID#" ); - - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); From f41017e6e6c6688b2fbb22ef06b99cdc8641d88d Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Jul 2022 17:32:45 -0500 Subject: [PATCH 47/75] formatting fixes --- tests/specs/integration/api-v5/RantsTest.cfc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index f0144ed..5633e9b 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -253,8 +253,11 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var testRant = queryExecute( "select id,userId from rants limit 1" ); - var event = put( "/api/v5/rants/#testRant.id#", { "userID" : createUUID(), "body" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v5/rants/#testRant.id#", + { "userID" : createUUID(), "body" : "" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -282,7 +285,10 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 400 error", function(){ var testRant = queryExecute( "select id,userId from rants limit 1" ); - var event = put( "/api/v5/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : "1" } ); + var event = put( + "/api/v5/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : "1" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -310,7 +316,10 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ var testRant = queryExecute( "select id,userId from rants limit 1" ); - var event = put( "/api/v5/rants/#testRant.id#", { "body" : "xsxswxws", "userID" : testRant.userId } ); + var event = put( + "/api/v5/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : testRant.userId } + ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); From 4760b5f34ed779fa3052a4ecf3884cbb92b9e5f8 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 Jul 2022 12:46:24 -0500 Subject: [PATCH 48/75] v6 models done --- .../api/modules_app/v5/ModuleConfig.cfc | 43 +------- .../api/modules_app/v6/ModuleConfig.cfc | 43 +------- .../api/modules_app/v6/config/Router.cfc | 18 ++-- .../api/modules_app/v6/models/BaseEntity.cfc | 89 ++++++++-------- .../api/modules_app/v6/models/BaseService.cfc | 100 ++++++++++++------ .../api/modules_app/v6/models/Rant.cfc | 22 ++-- .../api/modules_app/v6/models/RantService.cfc | 89 +++++----------- .../api/modules_app/v6/models/User.cfc | 10 +- .../api/modules_app/v6/models/UserService.cfc | 17 +-- 9 files changed, 177 insertions(+), 254 deletions(-) diff --git a/modules_app/api/modules_app/v5/ModuleConfig.cfc b/modules_app/api/modules_app/v5/ModuleConfig.cfc index d63c69a..4a823c0 100644 --- a/modules_app/api/modules_app/v5/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v5/ModuleConfig.cfc @@ -1,45 +1,6 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * v5 Module Config + */ component { // Module Properties diff --git a/modules_app/api/modules_app/v6/ModuleConfig.cfc b/modules_app/api/modules_app/v6/ModuleConfig.cfc index fd36862..bb70274 100644 --- a/modules_app/api/modules_app/v6/ModuleConfig.cfc +++ b/modules_app/api/modules_app/v6/ModuleConfig.cfc @@ -1,45 +1,6 @@ /** -Module Directives as public properties -this.title = "Title of the module"; -this.author = "Author of the module"; -this.webURL = "Web URL for docs purposes"; -this.description = "Module description"; -this.version = "Module Version"; -this.viewParentLookup = (true) [boolean] (Optional) // If true, checks for views in the parent first, then it the module.If false, then modules first, then parent. -this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks for layouts in the parent first, then it the module.If false, then modules first, then parent. -this.entryPoint = "" (Optional) // If set, this is the default event (ex:forgebox:manager.index) or default route (/forgebox) the framework - will use to create an entry link to the module. Similar to a default event. -this.cfmapping = "The CF mapping to create"; -this.modelNamespace = "The namespace to use for registered models, if blank it uses the name of the module." -this.dependencies = "The array of dependencies for this module" - -structures to create for configuration -- parentSettings : struct (will append and override parent) -- settings : struct -- interceptorSettings : struct of the following keys ATM - - customInterceptionPoints : string list of custom interception points -- interceptors : array -- layoutSettings : struct (will allow to define a defaultLayout for the module) -- routes : array Allowed keys are same as the addRoute() method of the SES interceptor. -- wirebox : The wirebox DSL to load and use - -Available objects in variable scope -- controller -- appMapping (application mapping) -- moduleMapping (include,cf path) -- modulePath (absolute path) -- log (A pre-configured logBox logger object for this object) -- binder (The wirebox configuration binder) -- wirebox (The wirebox injector) - -Required Methods -- configure() : The method ColdBox calls to configure the module. - -Optional Methods -- onLoad() : If found, it is fired once the module is fully loaded -- onUnload() : If found, it is fired once the module is unloaded - -*/ + * v6 Module Config + */ component { // Module Properties diff --git a/modules_app/api/modules_app/v6/config/Router.cfc b/modules_app/api/modules_app/v6/config/Router.cfc index 15761c1..b53af98 100644 --- a/modules_app/api/modules_app/v6/config/Router.cfc +++ b/modules_app/api/modules_app/v6/config/Router.cfc @@ -1,19 +1,15 @@ component { function configure(){ - // Echo - route( "/", "echo.index" ) - - // Type the ID to numeric - resources( - resource = "rants", - parameterName = "rantId-numeric", - except = [ "new", "edit" ] - ) - + // API Based Resourceful Routes: + // https://coldbox.ortusbooks.com/the-basics/routing/routing-dsl/resourceful-routes#api-resourceful-routes + apiResources( resource = "rants", parameterName = "rantId" ); // Catch All Invalid Routes - route( "/:anything", "Echo.onInvalidRoute" ) + route( "/:anything", "Echo.onInvalidRoute" ); + + // Entry Point + route( "/", "echo.index" ); } } diff --git a/modules_app/api/modules_app/v6/models/BaseEntity.cfc b/modules_app/api/modules_app/v6/models/BaseEntity.cfc index 55f359e..f97877b 100644 --- a/modules_app/api/modules_app/v6/models/BaseEntity.cfc +++ b/modules_app/api/modules_app/v6/models/BaseEntity.cfc @@ -1,14 +1,15 @@ /** - * I am the Base Entity + * I am a base entity which exposes some very cool methods to provide fluency and readability + * while still encapsulating them in a service. */ component accessors="true" { - // global properties - property name="pk"; - property name="entityName"; - property name="serviceName"; - property name="moduleName"; - property name="entityService"; + // Entity metadata + service + property name="_primaryKey"; + property name="_entityName"; + property name="_serviceName"; + property name="_moduleName"; + property name="_entityService"; // DI Injection property name="wirebox" inject="wirebox"; @@ -24,11 +25,11 @@ component accessors="true" { // An array of properties/relationships to NEVER include neverInclude : [ "password", - "pk", - "entityName", - "serviceName", - "moduleName", - "entityService" + "_primaryKey", + "_entityName", + "_serviceName", + "_moduleName", + "_entityService" ], // A struct of defaults for properties/relationships if they are null defaults : {}, @@ -39,44 +40,48 @@ component accessors="true" { /** * Initialize Entity - stores information needed * - * @pk The name of the primary key field in the entity + * @primaryKey The name of the primary key field in the entity * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards - * @serviceName The name of the service that manages the entity * @moduleName The name of the module for the objects + * @serviceName The name of the service that manages the entity */ function init( - pk = "id", + primaryKey = "id", entityName = "", - serviceName = "", - moduleName = "" + moduleName = "v6", + serviceName = "#arguments.entityName#Service@#arguments.moduleName#" ){ - setPk( arguments.pk ); - - if ( len( entityName ) ) { - setEntityName( arguments.entityName ); - } + variables._primaryKey = arguments.primaryKey; + variables._entityName = arguments.entityName; + variables._moduleName = arguments.moduleName; + variables._serviceName = arguments.serviceName; - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } - - setModuleName( arguments.moduleName ); - if ( arguments.moduleName != "" ) { - setServiceName( getServiceName() & "@" & arguments.moduleName ); - } + return this; } + /** + * Once this entity is loaded, load up it's companion service + */ function onDIComplete(){ - variables.entityService = wirebox.getInstance( getServiceName() ); + variables._entityService = wirebox.getInstance( variables._serviceName ); } /** * Verify if entity is loaded or not */ boolean function isLoaded(){ - return ( !structKeyExists( variables, getPk() ) OR !len( variables[ getPk() ] ) ? false : true ); + return ( + !structKeyExists( variables, variables._primaryKey ) OR !len( variables[ variables._primaryKey ] ) ? false : true + ); + } + + /** + * Get the primary key value of this object. + * + * @return The primary key or an empty value if not set. + */ + function getId(){ + return isLoaded() ? variables[ variables._primaryKey ] : ""; } /** @@ -113,19 +118,19 @@ component accessors="true" { string xml, query qry ){ - arguments[ "model" ] = this; - arguments.target = this; + // Seed the target for population + arguments[ "target" ] = this; // json? - if ( structKeyExists( arguments, "jsonstring" ) ) { + if ( !isNull( arguments.jsonstring ) ) { return variables.populator.populateFromJSON( argumentCollection = arguments ); } // XML - else if ( structKeyExists( arguments, "xml" ) ) { + else if ( !isNull( arguments.xml ) ) { return variables.populator.populateFromXML( argumentCollection = arguments ); } // Query - else if ( structKeyExists( arguments, "qry" ) ) { + else if ( !isNull( arguments.qry ) ) { return variables.populator.populateFromQuery( argumentCollection = arguments ); } // Mementos @@ -151,9 +156,9 @@ component accessors="true" { */ function save(){ if ( isLoaded() ) { - return variables.entityService.update( this ); + return variables._entityService.update( this ); } else { - return variables.entityService.create( this ); + return variables._entityService.create( this ); } } @@ -161,7 +166,7 @@ component accessors="true" { * Delete an entity */ function delete(){ - return variables.entityService.delete( this.getID() ); + return variables._entityService.delete( this.getId() ); } } diff --git a/modules_app/api/modules_app/v6/models/BaseService.cfc b/modules_app/api/modules_app/v6/models/BaseService.cfc index 9cc0387..920a3a7 100644 --- a/modules_app/api/modules_app/v6/models/BaseService.cfc +++ b/modules_app/api/modules_app/v6/models/BaseService.cfc @@ -1,5 +1,5 @@ /** - * I am the Base Service + * I am the Base Service v6 */ component accessors="true" { @@ -11,58 +11,60 @@ component accessors="true" { property name="entityName"; property name="tableName"; property name="primaryKey"; - // property name="parameterName"; property name="serviceName"; property name="moduleName"; + /** + * Constructorhonduras + * + * @entityName The name of the entity so we can reference it for calls to related DAO and Service. Set as optional for backwards + * @tableName The table name this service is bound to + * @primaryKey The primary key to use for operations + * @moduleName The name of the module for the objects + * @serviceName The name of the service that manages the entity + */ function init( entityName, tableName, primaryKey = "id", - // parameterName="", - serviceName = "", - moduleName = "" + moduleName = "v6", + serviceName = "#arguments.entityName#Service@#arguments.moduleName#" ){ setEntityName( arguments.entityName ); setTableName( arguments.tableName ); setPrimaryKey( arguments.primaryKey ); - // if( arguments.parameterName != "" ){ - // setParameterName( arguments.parameterName ); - // } else { - // setParameterName( arguments.primaryKey ); - // } - if ( arguments.serviceName != "" ) { - setServiceName( arguments.serviceName ); - } else { - setServiceName( arguments.entityName & "Service" ); - } + setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); - if ( arguments.moduleName != "" ) { - setServiceName( getServiceName() & "@" & arguments.moduleName ); - } + + return this; } /** - * Return a new Entity, empty or pre-populated with passed in data + * Get a new entity object according to entity name * - * @data Data to populate the new Entity with + * @properties The initial properties to populate the entity with + * + * @return A brand spanking new entity object */ - function new( struct data = {} ){ - var modelName = getEntityName() & ( getModuleName().len() ? "@#getModuleName()#" : "" ); - return populator.populateFromStruct( target = wireBox.getInstance( modelName ), memento = arguments.data ); + function new( struct properties = {} ){ + var entity = wirebox.getInstance( "#getEntityname()#@#getModuleName()#" ); + return populator.populateFromStruct( target = entity, memento = arguments.properties ); } /** - * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load + * Check to see if there is a row with a matching primary key in the database. + * Much faster than a full entity query and object load + * + * @id The primary key id to verify * * @return Returns true if there is a row with the matching Primary Key, otherwise returns false */ - boolean function exists(){ + boolean function exists( required id ){ return booleanFormat( queryExecute( - "select id from #getTableName()# - where #getPrimaryKey()# = :id", - { id : { value : arguments[ 1 ], cfsqltype : "cf_sql_numeric" } } + "select #getPrimaryKey()# from #getTableName()# + where #getPrimaryKey()# = :id", + { id : arguments.id } ).len() ) } @@ -70,30 +72,64 @@ component accessors="true" { /** * Check to see if there is a row with a matching primary key in the database. Much faster than a full entity query and object load * + * @id The primary key id to verify + * * @return Returns true if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function existsOrFail(){ + boolean function existsOrFail( required id ){ if ( exists( argumentCollection = arguments ) ) { return true; } - throw( type = "EntityNotFound", message = "#entityName# Not Found" ); + throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } /** * Query and load an entity if possible, else throw an error * + * @id The primary key id to retrieve + * * @return Returns the Entity if there is a row with the matching Primary Key * * @throws EntityNotFound if the entity is not found */ - function getOrFail(){ - var maybeEntity = this.get( argumentCollection = arguments ); + function getOrFail( required id ){ + var maybeEntity = this.get( arguments.id ); if ( !maybeEntity.isLoaded() ) { throw( type = "EntityNotFound", message = "#getEntityName()# Not Found" ); } return maybeEntity; } + /** + * Try to get an entity from the requested id + * + * @id The primary key id to retrieve + * + * @return Returns the Entity if there is a row with the matching Primary Key or an empty entity if not found + */ + function get( required id ){ + return queryExecute( + "select * from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id } + ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); + } + + /** + * Base delete entity + */ + function delete( required id ){ + queryExecute( + "delete from #getTableName()# + where #getPrimaryKey()# = :id + ", + { id : arguments.id }, + { result : "local.result" } + ); + return local.result; + } + } diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index c74c84a..cbf334a 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -1,10 +1,10 @@ /** * I am a new Rant Object */ -component extends="v5.models.BaseEntity" accessors="true" { +component extends="v6.models.BaseEntity" accessors="true" { // DI - property name="userService" inject="UserService@v5"; + property name="userService" inject="UserService@v6"; // Properties property name="id" type="string"; @@ -18,9 +18,9 @@ component extends="v5.models.BaseEntity" accessors="true" { body : { required : true }, userId : { required : true, - type : "numeric", + type : "uuid", udf : ( value, target ) => { - if ( isNull( arguments.value ) || !isNumeric( arguments.value ) ) return false + if ( isNull( arguments.value ) || !isValid( "uuid", arguments.value ) ) return false; return userService.exists( arguments.value ); }, udfMessage : "User ({rejectedValue}) not found" @@ -31,15 +31,21 @@ component extends="v5.models.BaseEntity" accessors="true" { * Constructor */ Rant function init(){ - super.init( entityName = "rant", moduleName = "v5" ); - return this; + return super.init( entityName = "rant" ); } /** - * getUser + * Get related user object */ function getUser(){ - return userService.get( getuserId() ); + return userService.get( getUserId() ); + } + + /** + * Does this rant have a user assigned to it already + */ + boolean function hasUser(){ + return !isNull( variables.userId ) && len( variables.userId ); } } diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index e0b431a..7383c4f 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -1,8 +1,8 @@ /** - * I am the Rant Service v5 + * I am the Rant Service v6 */ component - extends="v5.models.BaseService" + extends="v6.models.BaseService" singleton accessors="true" { @@ -12,10 +12,9 @@ component */ RantService function init(){ super.init( - entityName = "rant", + entityName = "Rant", tableName = "rants", - parameterName = "rantId", - moduleName = "v5" + parameterName = "rantId" ) return this; } @@ -28,84 +27,49 @@ component } ); } - function listArray(){ - return queryExecute( "select * from rants ORDER BY createdDate DESC", {} ).reduce( ( result, row ) => { - result.append( row ); - return result; - }, [] ); - } - - Rant function get( required numeric rantId ){ + array function listArray(){ return queryExecute( - "select * from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - - function delete( required numeric rantId ){ - queryExecute( - "delete from rants - where id = :rantId", - { rantId : { value : "#rantId#", cfsqltype : "cf_sql_numeric" } }, - { result : "local.result" } + "select * from rants ORDER BY createdDate DESC", + {}, + { returnType : "array" } ); - return local.result; } function create( required Rant rant ){ var now = now(); - arguments.rant.setCreatedDate( now ); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setId( createUUID() ); queryExecute( "insert into rants - set - body = :body, - userId = :userId, - createdDate = :createdDate, - updatedDate = :updatedDate + set + id = :rantId, + body = :body, + userId = :userId ", { - body : { + rantId : arguments.rant.getId(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, - userId : { - value : "#arguments.rant.getuserId()#", - cfsqltype : "cf_sql_numeric" - }, - createdDate : { - value : "#arguments.rant.getCreatedDate()#", - cfsqltype : "cf_sql_timestamp" - }, - updatedDate : { - value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" - } - }, - { result : "local.result" } + userId : arguments.rant.getuserId() + } ); - arguments.rant.setID( local.result.generatedKey ); return arguments.rant; } function update( required Rant rant ){ - var now = now(); - arguments.rant.setUpdatedDate( now ); + arguments.rant.setUpdatedDate( now() ); queryExecute( "update rants - set - body = :body, - updatedDate = :updatedDate - where id = :rantId + set + body = :body, + updatedDate = :updatedDate + where id = :rantId ", { - rantId : { - value : "#arguments.rant.getID()#", - cfsqltype : "cf_sql_integer" - }, - body : { + rantId : arguments.rant.getID(), + body : { value : "#arguments.rant.getBody()#", cfsqltype : "cf_sql_longvarchar" }, @@ -113,11 +77,8 @@ component value : "#arguments.rant.getUpdatedDate()#", cfsqltype : "cf_sql_timestamp" } - }, - { result : "local.result" } + } ); - return arguments.rant; } - } diff --git a/modules_app/api/modules_app/v6/models/User.cfc b/modules_app/api/modules_app/v6/models/User.cfc index 2b3ac93..f60a91b 100644 --- a/modules_app/api/modules_app/v6/models/User.cfc +++ b/modules_app/api/modules_app/v6/models/User.cfc @@ -1,7 +1,7 @@ /** * I am a new User Object */ -component extends="v5.models.BaseEntity" accessors="true" { +component extends="v6.models.BaseEntity" accessors="true" { // Properties property name="id" type="string"; @@ -11,12 +11,18 @@ component extends="v5.models.BaseEntity" accessors="true" { property name="createdDate" type="date"; property name="updatedDate" type="date"; + // Validation Constraints + this.constraints = { + username : { required : true }, + email : { required : true }, + password : { required : true } + }; /** * Constructor */ User function init(){ - super.init( entityName = "User", moduleName = "v5" ); + super.init( entityName = "User" ); return this; } diff --git a/modules_app/api/modules_app/v6/models/UserService.cfc b/modules_app/api/modules_app/v6/models/UserService.cfc index ad70e01..ef4a3ae 100644 --- a/modules_app/api/modules_app/v6/models/UserService.cfc +++ b/modules_app/api/modules_app/v6/models/UserService.cfc @@ -1,8 +1,8 @@ /** - * I am the User Service v5 + * I am the User Service v6 */ component - extends="v5.models.BaseService" + extends="v6.models.BaseService" singleton accessors="true" { @@ -12,20 +12,11 @@ component */ UserService function init(){ super.init( - entityName = "user", + entityName = "User", tableName = "users", - parameterName = "userId", - moduleName = "v5" + parameterName = "userId" ) return this; } - User function get( required numeric userId ){ - var q = queryExecute( - "select * from users - where id = :userId", - { userId : { value : "#userId#", cfsqltype : "cf_sql_numeric" } } - ).reduce( ( result, row ) => populator.populateFromStruct( result, row ), new () ); - } - } From 1de3b14e78e0a669a23af143cc7788c95280c570 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 Jul 2022 12:47:04 -0500 Subject: [PATCH 49/75] formatting --- modules_app/api/modules_app/v6/models/RantService.cfc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index 7383c4f..3aa2547 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -19,7 +19,7 @@ component return this; } - function list(){ + array function list(){ return this .listArray() .map( function( rant ){ @@ -81,4 +81,5 @@ component ); return arguments.rant; } + } From 2d7ca840cadff730f02846e68e83c7b2b9374901 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 16 Jul 2022 12:52:30 -0500 Subject: [PATCH 50/75] more wip for v6 --- .../api/modules_app/v6/handlers/Rants.cfc | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index 6423aa4..0474852 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -1,5 +1,10 @@ /** * My RESTFul Rants Event Handler which inherits from the module `api` + * Since we inherit from the RestHandler we get lots of goodies like automatic HTTP method protection, + * missing routes, invalid routes, and much more. + * + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler + * @see https://coldbox.ortusbooks.com/digging-deeper/rest-handler#rest-handler-security */ component extends="coldbox.system.RestHandler" { @@ -7,6 +12,16 @@ component extends="coldbox.system.RestHandler" { property name="rantService" inject="RantService@v6"; property name="userService" inject="UserService@v6"; + /** + * Param global incoming variables + */ + any function preHandler( event, rc, prc, action, eventArguments ){ + param rc.rantId = ""; + param rc.includes = ""; + param rc.excludes = ""; + param rc.ignoreDefaults = false; + } + /** * * Returns a list of Rants @@ -15,7 +30,15 @@ component extends="coldbox.system.RestHandler" { * @response-200 ~api-v6/Rants/index/responses.json##200 */ any function index( event, rc, prc ) cache=true cacheTimeout=60{ - prc.response.setData( rantService.list().map( ( rant ) => rant.getMemento() ) ); + prc.response.setData( + rantService + .list() + .map( ( rant ) => rant.getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) ) + ); } /** @@ -28,7 +51,15 @@ component extends="coldbox.system.RestHandler" { * @response-404 ~_responses/rant.404.json */ function show( event, rc, prc ) cache=true cacheTimeout=60{ - prc.response.setData( rantService.getOrFail( rc.rantId ).getMemento() ); + prc.response.setData( + rantService + .getOrFail( rc.rantId ) + .getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) + ); } /** @@ -42,7 +73,6 @@ component extends="coldbox.system.RestHandler" { */ function delete( event, rc, prc ){ rantService.getOrFail( rc.rantId ).delete(); - prc.response.addMessage( "Rant deleted" ); } @@ -56,12 +86,20 @@ component extends="coldbox.system.RestHandler" { * @response-400 ~api-v6/Rants/create/responses.json##400 */ function create( event, rc, prc ){ - var result = rantService + var rant = rantService .new( rc ) .validateOrFail() .save(); - prc.response.setData( { "rantId" : result.getID() } ).addMessage( "Rant created" ); + prc.response + .setData( + rant.getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) + ) + .addMessage( "Rant created" ); getCache( "template" ).clearAllEvents(); } @@ -76,13 +114,21 @@ component extends="coldbox.system.RestHandler" { * @response-400 ~api-v6/Rants/update/responses.json##400 */ function update( event, rc, prc ){ - rantService + var rant = rantService .getOrFail( rc.rantId ) .populate( memento = rc, exclude = "id" ) .validateOrFail() .save(); - prc.response.addMessage( "Rant Updated" ); + prc.response + .setData( + rant.getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) + ) + .addMessage( "Rant Updated" ); getCache( "template" ).clearAllEvents(); } From 271d79daffbb62be322eab1e4434d55c4785459b Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 08:06:49 -0500 Subject: [PATCH 51/75] v6 wip --- .../api/modules_app/v6/handlers/Rants.cfc | 50 ++++++++----------- tests/specs/integration/api-v6/RantsTest.cfc | 10 ++-- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/modules_app/api/modules_app/v6/handlers/Rants.cfc b/modules_app/api/modules_app/v6/handlers/Rants.cfc index 0474852..56c70a3 100644 --- a/modules_app/api/modules_app/v6/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v6/handlers/Rants.cfc @@ -13,7 +13,7 @@ component extends="coldbox.system.RestHandler" { property name="userService" inject="UserService@v6"; /** - * Param global incoming variables + * Param global incoming variables for the endpoint */ any function preHandler( event, rc, prc, action, eventArguments ){ param rc.rantId = ""; @@ -23,7 +23,6 @@ component extends="coldbox.system.RestHandler" { } /** - * * Returns a list of Rants * * @x-route (GET) /api/v6/rants @@ -42,8 +41,7 @@ component extends="coldbox.system.RestHandler" { } /** - * - * Display a single Rant. + * Return a single Rant by id * * @x-route (GET) /api/v6/rants/:rantId * @x-parameters ~api-v6/Rants/show/parameters.json##parameters @@ -63,7 +61,6 @@ component extends="coldbox.system.RestHandler" { } /** - * * Delete a single Rant. * * @x-route (DELETE) /api/v6/rants/:rantId @@ -74,10 +71,10 @@ component extends="coldbox.system.RestHandler" { function delete( event, rc, prc ){ rantService.getOrFail( rc.rantId ).delete(); prc.response.addMessage( "Rant deleted" ); + getCache( "template" ).clearAllEvents(); } /** - * * Creates a new Rant. * * @x-route (POST) /api/v1/rants @@ -86,18 +83,17 @@ component extends="coldbox.system.RestHandler" { * @response-400 ~api-v6/Rants/create/responses.json##400 */ function create( event, rc, prc ){ - var rant = rantService - .new( rc ) - .validateOrFail() - .save(); - prc.response .setData( - rant.getMemento( - includes : rc.includes, - excludes : rc.excludes, - ignoreDefaults: rc.ignoreDefaults - ) + rantService + .new( rc ) + .validateOrFail() + .save() + .getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) ) .addMessage( "Rant created" ); @@ -105,7 +101,6 @@ component extends="coldbox.system.RestHandler" { } /** - * * Update an existing Rant. * * @x-route (PUT) /api/v1/rants/:rantId @@ -114,19 +109,18 @@ component extends="coldbox.system.RestHandler" { * @response-400 ~api-v6/Rants/update/responses.json##400 */ function update( event, rc, prc ){ - var rant = rantService - .getOrFail( rc.rantId ) - .populate( memento = rc, exclude = "id" ) - .validateOrFail() - .save(); - prc.response .setData( - rant.getMemento( - includes : rc.includes, - excludes : rc.excludes, - ignoreDefaults: rc.ignoreDefaults - ) + rantService + .getOrFail( rc.rantId ) + .populate( memento = rc, exclude = "id" ) + .validateOrFail() + .save() + .getMemento( + includes : rc.includes, + excludes : rc.excludes, + ignoreDefaults: rc.ignoreDefaults + ) ) .addMessage( "Rant Updated" ); diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 887226f..afa3145 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -7,7 +7,7 @@ component extends="tests.resources.BaseTest" { setup(); } ); - scenario( "Get a list of Rants", function(){ + story( "Get a list of Rants", function(){ given( "I make a get call to /api/v6/rants", function(){ when( "I have no search filters", function(){ then( "I will get a list of Rants", function(){ @@ -25,7 +25,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - scenario( "Get an individual Rant", function(){ + story( "Get an individual Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "I pass an invalid rantID", function(){ then( "it will be ignored and get the full listing", function(){ @@ -75,7 +75,7 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Create a Rant", function(){ + story( "Create a Rant", function(){ given( "I make a post call to /api/v6/rants", function(){ when( "Using a get method", function(){ then( "I will hit the index action instead of the create action", function(){ @@ -186,7 +186,7 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Update a Rant", function(){ + story( "Update a Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ @@ -326,7 +326,7 @@ component extends="tests.resources.BaseTest" { } ); - scenario( "Delete a Rant", function(){ + story( "Delete a Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "Using a get method", function(){ then( "I will hit the show action instead of the update action", function(){ From 0850ce47a4845a0f493c0d32abb6b0d20b6cf3d7 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 08:59:16 -0500 Subject: [PATCH 52/75] v6 done --- tests/specs/integration/api-v6/RantsTest.cfc | 140 ++++++++++--------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index afa3145..b90eb00 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -28,20 +28,22 @@ component extends="tests.resources.BaseTest" { story( "Get an individual Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "I pass an invalid rantID", function(){ - then( "it will be ignored and get the full listing", function(){ + then( "I will get a 404 error", function(){ var rantID = "x" - var event = get( "/api/v6/rants/#rantID#" ); + var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); - expect( returnedJSON.data ).toBeArray() - expect( returnedJSON.data ).toHaveLengthGTE( 1 ); + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeTrue(); + expect( event ).toHaveStatusCode( 404 ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); when( "I pass a valid but non existing rantID", function(){ then( "I will get a 404 error", function(){ - var rantID = "1" + var rantID = createUUID(); var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); @@ -56,8 +58,8 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid and existing rantID", function(){ then( "I will get a single Rant returned", function(){ - var rantID = 7; - var event = get( "/api/v6/rants/#rantID#" ); + var testRantId = queryExecute( "select id from rants limit 1" ).id; + var event = get( "/api/v6/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); @@ -65,7 +67,6 @@ component extends="tests.resources.BaseTest" { expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); - expect( returnedJSON.data.id ).toBe( 7 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -74,7 +75,6 @@ component extends="tests.resources.BaseTest" { } ); } ); - story( "Create a Rant", function(){ given( "I make a post call to /api/v6/rants", function(){ when( "Using a get method", function(){ @@ -113,7 +113,7 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; @@ -128,7 +128,7 @@ component extends="tests.resources.BaseTest" { when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v6/rants", { "userID" : "5" } ); + var event = post( "/api/v6/rants", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -141,7 +141,7 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v6/rants", { "userID" : "5", "body" : "" } ); + var event = post( "/api/v6/rants", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -154,7 +154,7 @@ component extends="tests.resources.BaseTest" { when( "Including valid userID for a non existing User", function(){ then( "I will get a 400 error", function(){ - var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : "1" } ); + var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -167,15 +167,15 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID", function(){ then( "I will get a successful query result with a generatedKey", function(){ - var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : "5" } ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); + expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -185,7 +185,6 @@ component extends="tests.resources.BaseTest" { } ); } ); - story( "Update a Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "Using a get method", function(){ @@ -212,8 +211,8 @@ component extends="tests.resources.BaseTest" { when( "Including an empty userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v6/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -224,10 +223,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric userID param", function(){ + when( "Including a non uuid userID param", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "abc" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v6/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -238,11 +237,10 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including no body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v6/rants/#testRant.id#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -255,8 +253,11 @@ component extends="tests.resources.BaseTest" { when( "Including an empty body param", function(){ then( "I will get a 400 error", function(){ - var rantID = "4"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "1", "body" : "" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v6/rants/#testRant.id#", + { "userID" : createUUID(), "body" : "" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -267,21 +268,27 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ - then( "I will get a 405 error because we only accept numeric Ids", function(){ - var rantID = "abc"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); + when( "Including a non uuid rantID param", function(){ + then( "I will get a 400 error", function(){ + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; + expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON.messages.toString() ).toInclude( "InvalidHTTPMethod" ); + expect( event ).toHaveStatusCode( 400 ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); when( "Including valid userID for a non existing User", function(){ then( "I will get a 400 error", function(){ - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "body" : "xsxswxws", "userID" : "1" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v6/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : createUUID() } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -294,8 +301,11 @@ component extends="tests.resources.BaseTest" { when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = "1"; - var event = put( "/api/v6/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); + var rantID = createUUID(); + var event = put( + "/api/v6/rants/#rantID#", + { "userID" : createUUID(), "body" : "xsxswxws" } + ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); @@ -308,8 +318,11 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid body and userID and rantID", function(){ then( "I will update the Rant Successfully", function(){ - var rantID = "7"; - var event = put( "/api/v6/rants/#rantID#", { "body" : "xsxswxws", "userID" : "5" } ); + var testRant = queryExecute( "select id,userId from rants limit 1" ); + var event = put( + "/api/v6/rants/#testRant.id#", + { "body" : "xsxswxws", "userID" : testRant.userId } + ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -325,7 +338,6 @@ component extends="tests.resources.BaseTest" { } ); } ); - story( "Delete a Rant", function(){ given( "I make a get call to /api/v6/rants/:rantID", function(){ when( "Using a get method", function(){ @@ -361,20 +373,19 @@ component extends="tests.resources.BaseTest" { } ); } ); - when( "Including a non numeric rantID param", function(){ - then( "I will get a 400 error", function(){ + when( "Including a non uuid rantID param", function(){ + then( "I will get a 404 error", function(){ var rantID = "abc"; var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON.messages.toString() ).toInclude( "InvalidHTTPMethod" ); + expect( event ).toHaveStatusCode( 404 ); } ); } ); when( "Including valid rantID for a non existing Rant", function(){ then( "I will get a 404 error", function(){ - var rantID = 1; + var rantID = createUUID(); var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); @@ -388,24 +399,25 @@ component extends="tests.resources.BaseTest" { when( "I pass a valid rantID", function(){ then( "I will delete the rant successfully", function(){ - var event = post( - "/api/v6/rants", - { "body" : "New Rant Created to Delete", "userID" : "5" } - ); + var testUserId = queryExecute( "select id from users limit 1" ).id; + var rantService = getInstance( "RantService@v4" ); + var testRant = rantService + .new() + .setId( createUUID() ) + .setBody( "integration testing is lovely!" ) + .setUserId( testUserId ); + rantService.create( testRant ); + + var event = delete( "/api/v6/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - setup(); - var rantID = returnedJSON.data.rantID; - var event2 = delete( "/api/v6/rants/#rantID#" ); - - var returnedJSON2 = event2.getRenderData().data; - expect( returnedJSON2 ).toHaveKeyWithCase( "error" ); - expect( returnedJSON2.error ).toBeFalse(); - expect( event2.getStatusCode() ).toBe( 200 ); - expect( returnedJSON2 ).toHaveKeyWithCase( "data" ); - expect( returnedJSON2 ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON2.messages ).toBeArray(); - expect( returnedJSON2.messages ).toHaveLengthGTE( 1 ); - expect( returnedJSON2.messages[ 1 ] ).toBe( "Rant Deleted" ); + expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON.error ).toBeFalse(); + expect( event.getStatusCode() ).toBe( 200 ); + expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.messages ).toBeArray(); + expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); + expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); } ); From a6eb9d08986db1c636838136fdfed55adcd89371 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:05:27 -0500 Subject: [PATCH 53/75] github actions --- .github/FUNDING.YML | 1 + .github/workflows/ci.yml | 15 +++ .github/workflows/pr.yml | 27 ++++++ .github/workflows/tests.yml | 97 +++++++++++++++++++ server.json => server-adobe.json | 0 .../{20200507_fluentapi.sql => fluentapi.sql} | 0 6 files changed, 140 insertions(+) create mode 100644 .github/FUNDING.YML create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/tests.yml rename server.json => server-adobe.json (100%) rename workbench/database/{20200507_fluentapi.sql => fluentapi.sql} (100%) diff --git a/.github/FUNDING.YML b/.github/FUNDING.YML new file mode 100644 index 0000000..7e59d13 --- /dev/null +++ b/.github/FUNDING.YML @@ -0,0 +1 @@ +patreon: ortussolutions diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0c21d07 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,15 @@ +name: Modern Fluent API CI + +# Only on Development we build snapshots +on: + push: + branches: + - development + - master + +jobs: + ############################################# + # Tests First baby! We fail, no build :( + ############################################# + tests: + uses: ./.github/workflows/tests.yml diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..780de94 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,27 @@ +name: Pull Requests + +on: + pull_request: + branches: + - development + +jobs: + tests: + uses: lmajano/modern-functional-fluent-cfml-rest/.github/workflows/tests.yml@development + + # Format PR + format: + name: Format + runs-on: ubuntu-20.04 + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - uses: Ortus-Solutions/commandbox-action@v1.0.2 + with: + cmd: run-script format + + - name: Commit Format Changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Apply cfformat changes diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..2a6e659 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,97 @@ +name: Test Suites + +# We are a reusable Workflow only +on: + workflow_call: + +jobs: + tests: + name: Tests + runs-on: ubuntu-20.04 + env: + DB_USER: root + DB_PASSWORD: root + strategy: + fail-fast: false + matrix: + cfengine: [ "lucee", "adobe" ] + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Setup Java + uses: actions/setup-java@v2 + with: + distribution: "adopt" + java-version: "11" + + - name: Setup Database and Fixtures + run: | + sudo systemctl start mysql.service + # Create Database + mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} -e 'CREATE DATABASE fluentapi;' + # Import Database + mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} < workbench/database/fluentapi.sql + + - name: Setup Environment For Testing Process + run: | + # Setup .env + touch .env + # ENV + printf "ENVIRONMENT=development\n" >> .env + printf "DB_HOST=localhost\n" >> .env + printf "DB_USER=${{ env.DB_USER }}\n" >> .env + printf "DB_PASSWORD=${{ env.DB_PASSWORD }}\n" >> .env + printf "DB_CLASS=com.mysql.cj.jdbc.Driver\n" >> .env + printf "DB_BUNDLEVERSION=8.0.19\n" >> .env + printf "DB_BUNDLENAME=com.mysql.cj\n" >> .env + + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@main + + - name: Install Dependencies + run: | + box install + + - name: Start ${{ matrix.cfengine }} Server + run: | + box server start serverConfigFile="server-${{ matrix.cfengine }}.json" --noSaveSettings --debug + # Install Adobe 2021 cfpm modules + if [[ "${{ matrix.cfengine }}" == "adobe@2021" ]] ; then + box run-script install:2021 + fi + curl http://127.0.0.1:60146 + + - name: Run Tests + run: | + mkdir -p tests/results + box testbox run --verbose outputFile=tests/results/test-results outputFormats=json,antjunit + + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v1 + if: always() + with: + files: tests/results/**/*.xml + check_name: "${{ matrix.cfengine }} Test Results" + + - name: Upload Test Results to Artifacts + if: always() + uses: actions/upload-artifact@v2 + with: + name: test-results-${{ matrix.cfengine }} + path: | + tests/results/**/* + + - name: Failure Debugging Log + if: ${{ failure() }} + run: | + box server log serverConfigFile="server-${{ matrix.cfengine }}.json" + + - name: Upload Debugging Log To Artifacts + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: Failure Debugging Info - ${{ matrix.cfengine }} + path: | + .engine/**/logs/* + .engine/**/WEB-INF/cfusion/logs/* diff --git a/server.json b/server-adobe.json similarity index 100% rename from server.json rename to server-adobe.json diff --git a/workbench/database/20200507_fluentapi.sql b/workbench/database/fluentapi.sql similarity index 100% rename from workbench/database/20200507_fluentapi.sql rename to workbench/database/fluentapi.sql From 4d126536ef4cc65c6bf7761bb550bd34ec3b3fa3 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:08:39 -0500 Subject: [PATCH 54/75] fixing db updates --- config/Coldbox.cfc | 2 +- workbench/database/fluentapi.sql | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 228eb65..0f665ca 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -154,7 +154,7 @@ */ cbswagger : { // The route prefix to search. Routes beginning with this prefix will be determined to be api routes - "routes" : [ "api" ], + "routes" : [ "api/v6" ], // Any routes to exclude "excludeRoutes" : [], // The default output format: json or yml diff --git a/workbench/database/fluentapi.sql b/workbench/database/fluentapi.sql index cd7ee48..a9cb615 100644 --- a/workbench/database/fluentapi.sql +++ b/workbench/database/fluentapi.sql @@ -10,6 +10,7 @@ # Generation Time: 2022-07-13 23:41:21 +0000 # ************************************************************ +USE fluentapi; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; From b1d0a25df059018996f7846dd759ecb748b8b679 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:15:46 -0500 Subject: [PATCH 55/75] remove cbdebugger for ci tests --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2a6e659..6158471 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,6 +45,7 @@ jobs: printf "DB_CLASS=com.mysql.cj.jdbc.Driver\n" >> .env printf "DB_BUNDLEVERSION=8.0.19\n" >> .env printf "DB_BUNDLENAME=com.mysql.cj\n" >> .env + printf "CBDEBUGGER_ENABLED=false\n" >> .env - name: Setup CommandBox CLI uses: Ortus-Solutions/setup-commandbox@main From 578f370dd29847e8d77ec5caa6621700dc713251 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:25:42 -0500 Subject: [PATCH 56/75] embedded users --- modules_app/api/modules_app/v6/models/Rant.cfc | 13 ++++++++++++- tests/specs/integration/api-v6/RantsTest.cfc | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/modules_app/api/modules_app/v6/models/Rant.cfc b/modules_app/api/modules_app/v6/models/Rant.cfc index cbf334a..eb39ca0 100644 --- a/modules_app/api/modules_app/v6/models/Rant.cfc +++ b/modules_app/api/modules_app/v6/models/Rant.cfc @@ -31,7 +31,18 @@ component extends="v6.models.BaseEntity" accessors="true" { * Constructor */ Rant function init(){ - return super.init( entityName = "rant" ); + super.init( entityName = "rant" ); + + // Custom Includes + this.memento.defaultIncludes = [ + "id:rantId", + "body", + "createdDate", + "updatedDate", + "user" + ]; + + return this; } /** diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index b90eb00..277b92d 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -66,7 +66,7 @@ component extends="tests.resources.BaseTest" { expect( event ).toHaveStatusCode( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -175,7 +175,7 @@ component extends="tests.resources.BaseTest" { expect( event.getStatusCode() ).toBe( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); + expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); From 11b3379d59df5486e92b3c34f4cd593a345e8a27 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:37:24 -0500 Subject: [PATCH 57/75] updated readme --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index 569b813..df31695 100644 --- a/readme.md +++ b/readme.md @@ -55,9 +55,14 @@ http://127.0.0.1:60146/cbswagger #### What can you do with the API Docs? +- Immport into Insomnia: https://insomnia.rest/ - Import into Postman: https://www.postman.com/ - Use with Swagger.io site: https://editor.swagger.io/ ### View Route Visualizer http://127.0.0.1:60146/route-visualizer + +### View CBDebugger + +http://127.0.0.1:60146/cbdebugger From 5925d6b7de647f71a48a5b05504258fd4b76f176 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:39:54 -0500 Subject: [PATCH 58/75] added db_databse env --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6158471..ced5e1e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,6 +40,7 @@ jobs: # ENV printf "ENVIRONMENT=development\n" >> .env printf "DB_HOST=localhost\n" >> .env + printf "DB_DATABASE=fluentapi\n" >> .env printf "DB_USER=${{ env.DB_USER }}\n" >> .env printf "DB_PASSWORD=${{ env.DB_PASSWORD }}\n" >> .env printf "DB_CLASS=com.mysql.cj.jdbc.Driver\n" >> .env From 4ad6078175d9bafa9d05a01811ed3a8a7de49c8f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 18 Jul 2022 09:40:29 -0500 Subject: [PATCH 59/75] cbdebugger env --- config/Coldbox.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 0f665ca..15f5c1b 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -242,7 +242,7 @@ variables.modulesettings.cbdebugger = { // This flag enables/disables the tracking of request data to our storage facilities // To disable all tracking, turn this master key off - enabled : true, // getSystemSetting( "CBDEBUGGER_ENABLED", false ), + enabled : getSystemSetting( "CBDEBUGGER_ENABLED", false ), // This setting controls if you will activate the debugger for visualizations ONLY // The debugger will still track requests even in non debug mode. debugMode : true, From 9f743675bed3bad07ced173047d103f64ac4ba58 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 12:52:21 +0200 Subject: [PATCH 60/75] update to all new dependencies and migrations --- .cfmigrations.json | 20 ++++++++++++++++++++ .gitignore | 2 ++ box.json | 30 +++++++----------------------- config/.htaccess | 4 ---- index.cfm | 8 +++----- robots.txt | 33 --------------------------------- server-adobe.json | 10 ++++++++-- server-boxlang.json | 15 +++++++++++++++ 8 files changed, 55 insertions(+), 67 deletions(-) create mode 100755 .cfmigrations.json delete mode 100644 config/.htaccess delete mode 100644 robots.txt create mode 100644 server-boxlang.json diff --git a/.cfmigrations.json b/.cfmigrations.json new file mode 100755 index 0000000..dfb3a79 --- /dev/null +++ b/.cfmigrations.json @@ -0,0 +1,20 @@ +{ + "default": { + "manager": "cfmigrations.models.QBMigrationManager", + "migrationsDirectory": "resources/database/migrations/", + "seedsDirectory": "resources/database/seeds/", + "properties": { + "defaultGrammar": "AutoDiscover@qb", + "schema": "${DB_DATABASE}", + "migrationsTable": "cfmigrations", + "connectionInfo": { + "connectionString": "${DB_CONNECTIONSTRING}", + "class": "${DB_CLASS}", + "username": "${DB_USER}", + "password": "${DB_PASSWORD}", + "bundleName": "${DB_BUNDLENAME}", + "bundleVersion": "${DB_BUNDLEVERSION}" + } + } + } +} diff --git a/.gitignore b/.gitignore index 4850a34..dd44d5e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ settings.xml WEB-INF .env .engine/** +bin/** +grapher/** # logs + tests logs/** diff --git a/box.json b/box.json index afca93c..747b704 100644 --- a/box.json +++ b/box.json @@ -20,7 +20,7 @@ "devDependencies":{ "relax":"*", "route-visualizer":"*", - "testbox":"*", + "testbox":"be", "commandbox-dotenv":"*", "commandbox-docbox":"*", "commandbox-cfconfig":"*", @@ -28,12 +28,12 @@ "commandbox-migrations":"*" }, "dependencies":{ - "coldbox":"^6.7.0+3", - "cbswagger":"^2.6.0+147", - "cbvalidation":"^3.4.0+14", - "cors":"^3.0.0", - "mementifier":"^2.8.0+4", - "cbdebugger":"^3.4.0+61" + "coldbox":"^7", + "cbswagger":"^3", + "cbvalidation":"^4", + "cors":"^3", + "mementifier":"^3", + "cbdebugger":"^4" }, "installPaths":{ "coldbox":"coldbox/", @@ -52,9 +52,6 @@ "scripts":{ "start:lucee":"server start serverConfigFile=server-lucee.json --force", "start:adobe":"server start serverConfigFile=server.json --force", - "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", - "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", - "install:2021":"run-script cfpm:install mysql,debugger,chart", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", @@ -64,18 +61,5 @@ "test:v4":"testbox run directory=tests/specs/integration/api-v4", "test:v5":"testbox run directory=tests/specs/integration/api-v5", "test:v6":"testbox run directory=tests/specs/integration/api-v6" - }, - "cfmigrations":{ - "migrationsDirectory":"resources/database/migrations", - "schema":"${DB_DATABASE}", - "connectionInfo":{ - "bundleName":"${DB_BUNDLENAME}", - "bundleVersion":"${DB_BUNDLEVERSION}", - "password":"${DB_PASSWORD}", - "connectionString":"${DB_CONNECTIONSTRING}", - "class":"${DB_CLASS}", - "username":"${DB_USER}" - }, - "defaultGrammar":"AutoDiscover@qb" } } diff --git a/config/.htaccess b/config/.htaccess deleted file mode 100644 index 7a9f53d..0000000 --- a/config/.htaccess +++ /dev/null @@ -1,4 +0,0 @@ -#apache access file to protect the config.xml.cfm file. Delete this if you do not use apache. -authtype Basic -deny from all -Options -Indexes \ No newline at end of file diff --git a/index.cfm b/index.cfm index 7331009..a11a3fc 100644 --- a/index.cfm +++ b/index.cfm @@ -1,9 +1,7 @@ - - - diff --git a/robots.txt b/robots.txt deleted file mode 100644 index dfd0764..0000000 --- a/robots.txt +++ /dev/null @@ -1,33 +0,0 @@ - -User-agent: Slurp -Crawl-delay: 100 -Disallow: - -User-agent: gsa-crawler-www -Crawl-delay: 100 - -User-agent: Googlebot -Crawl-delay: 100 - -User-agent: Mediapartners-Google -Disallow: - -User-agent: Yahoo-NewsCrawler -Disallow: - -User-Agent: msnbot -Crawl-delay: 100 -Disallow: - -User-Agent: * -Disallow: /config/ -Disallow: /handlers/ -Disallow: /includes/ -Disallow: /interceptors/ -Disallow: /layouts/ -Disallow: /logs/ -Disallow: /models/ -Disallow: /modules/ -Disallow: /modules_app/ -Disallow: /views/ -Allow: / diff --git a/server-adobe.json b/server-adobe.json index 30161e5..b00c5ed 100644 --- a/server-adobe.json +++ b/server-adobe.json @@ -1,8 +1,8 @@ { "name":"fluentapi-adobe", "app":{ - "serverHomeDirectory":".engine/adobe2021", - "cfengine":"adobe@2021" + "serverHomeDirectory":".engine/adobe2023", + "cfengine":"adobe@2023" }, "web":{ "http":{ @@ -11,5 +11,11 @@ "rewrites":{ "enable":"true" } + }, + "cfconfig":{ + "file":".cfconfig.json" + }, + "scripts":{ + "onServerInstall":"cfpm install mysql,debugger,chart" } } diff --git a/server-boxlang.json b/server-boxlang.json new file mode 100644 index 0000000..a8ee0ef --- /dev/null +++ b/server-boxlang.json @@ -0,0 +1,15 @@ +{ + "name":"fluentapi-boxlang", + "app":{ + "serverHomeDirectory":".engine/boxlang", + "cfengine":"boxlang@1" + }, + "web":{ + "http":{ + "port":"60146" + }, + "rewrites":{ + "enable":"true" + } + } +} From 5193653c30b24efbba9fc94d4f338cb99b1b7bc2 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 12:59:59 +0200 Subject: [PATCH 61/75] modules config --- config/Coldbox.cfc | 194 +-------------------------------- config/Router.cfc | 18 ++- config/Scheduler.cfc | 2 +- config/modules/cbdebugger.cfc | 93 ++++++++++++++++ config/modules/cbswagger.cfc | 79 ++++++++++++++ config/modules/mementifier.cfc | 26 +++++ 6 files changed, 215 insertions(+), 197 deletions(-) create mode 100644 config/modules/cbdebugger.cfc create mode 100644 config/modules/cbswagger.cfc create mode 100644 config/modules/mementifier.cfc diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc index 15f5c1b..eb3e396 100644 --- a/config/Coldbox.cfc +++ b/config/Coldbox.cfc @@ -2,6 +2,7 @@ /** * Configure the ColdBox App For Production + * https://coldbox.ortusbooks.com/getting-started/configuration */ function configure(){ /** @@ -125,108 +126,7 @@ * * } */ - moduleSettings = { - /** - * Mementifier settings: https://forgebox.io/view/mementifier - */ - mementifier : { - // Turn on to use the ISO8601 date/time formatting on all processed date/time properites, else use the masks - iso8601Format : true, - // The default date mask to use for date properties - dateMask : "yyyy-MM-dd", - // The default time mask to use for date properties - timeMask : "HH:mm: ss", - // Enable orm auto default includes: If true and an object doesn't have any `memento` struct defined - // this module will create it with all properties and relationships it can find for the target entity - // leveraging the cborm module. - ormAutoIncludes : true, - // The default value for relationships/getters which return null - nullDefaultValue : "", - // Don't check for getters before invoking them - trustedGetters : false, - // If not empty, convert all date/times to the specific timezone - convertToTimezone : "UTC" - }, - /** - * -------------------------------------------------------------------------- - * cbSwagger Settings - * -------------------------------------------------------------------------- - */ - cbswagger : { - // The route prefix to search. Routes beginning with this prefix will be determined to be api routes - "routes" : [ "api/v6" ], - // Any routes to exclude - "excludeRoutes" : [], - // The default output format: json or yml - "defaultFormat" : "json", - // A convention route, relative to your app root, where request/response samples are stored ( e.g. resources/apidocs/responses/[module].[handler].[action].[HTTP Status Code].json ) - "samplesPath" : "resources/apidocs", - // Information about your API - "info" : { - // A title for your API - "title" : "Fluent API for SoapBox Twitter clone", - // A description of your API - "description" : "This Fluent API provides data the for SoapBox Twitter clone", - // A terms of service URL for your API - "termsOfService" : "", - // The contact email address - "contact" : { - "name" : "Gavin Pickin", - "url" : "https://www.ortussolutions.com", - "email" : "gavin@ortussolutions.com" - }, - // A url to the License of your API - "license" : { - "name" : "Apache 2.0", - "url" : "https://www.apache.org/licenses/LICENSE-2.0.html" - }, - // The version of your API - "version" : "1.0.0" - }, - // Tags - "tags" : [], - // https://swagger.io/specification/#externalDocumentationObject - "externalDocs" : { - "description" : "Find more info here", - "url" : "https://blog.readme.io/an-example-filled-guide-to-swagger-3-2/" - }, - // https://swagger.io/specification/#serverObject - "servers" : [ - { - "url" : "http://127.0.0.1:60146", - "description" : "Local development" - } - ], - // An element to hold various schemas for the specification. - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject - "components" : { - // Define your security schemes here - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject - "securitySchemes" : { - // "ApiKeyAuth" : { - // "type" : "apiKey", - // "description" : "User your JWT as an Api Key for security", - // "name" : "x-api-key", - // "in" : "header" - // }, - // "bearerAuth" : { - // "type" : "http", - // "scheme" : "bearer", - // "bearerFormat" : "JWT" - // } - } - } - - // A default declaration of Security Requirement Objects to be used across the API. - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securityRequirementObject - // Only one of these requirements needs to be satisfied to authorize a request. - // Individual operations may set their own requirements with `@security` - // "security" : [ - // { "APIKey" : [] }, - // { "UserSecurity" : [] } - // ] - } - }; + moduleSettings = {}; } /** @@ -237,96 +137,6 @@ coldbox.handlerCaching = false; coldbox.reinitpassword = ""; coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; - - // Debugger Settings - variables.modulesettings.cbdebugger = { - // This flag enables/disables the tracking of request data to our storage facilities - // To disable all tracking, turn this master key off - enabled : getSystemSetting( "CBDEBUGGER_ENABLED", false ), - // This setting controls if you will activate the debugger for visualizations ONLY - // The debugger will still track requests even in non debug mode. - debugMode : true, - // The URL password to use to activate it on demand - debugPassword : "cb", - // This flag enables/disables the end of request debugger panel docked to the bottom of the page. - // If you disable it, then the only way to visualize the debugger is via the `/cbdebugger` endpoint - requestPanelDock : true, - // Request Tracker Options - requestTracker : { - storage : "cachebox", - cacheName : "template", - trackDebuggerEvents : false, - // Expand by default the tracker panel or not - expanded : true, - // Slow request threshold in milliseconds, if execution time is above it, we mark those transactions as red - slowExecutionThreshold : 1000, - // How many tracking profilers to keep in stack: Default is to monitor the last 20 requests - maxProfilers : 50, - // If enabled, the debugger will monitor the creation time of CFC objects via WireBox - profileWireBoxObjectCreation : false, - // Profile model objects annotated with the `profile` annotation - profileObjects : true, - // If enabled, will trace the results of any methods that are being profiled - traceObjectResults : false, - // Profile Custom or Core interception points - profileInterceptions : false, - // By default all interception events are excluded, you must include what you want to profile - includedInterceptions : [], - // Control the execution timers - executionTimers : { - expanded : true, - // Slow transaction timers in milliseconds, if execution time of the timer is above it, we mark it - slowTimerThreshold : 250 - }, - // Control the coldbox info reporting - coldboxInfo : { expanded : false }, - // Control the http request reporting - httpRequest : { - expanded : false, - // If enabled, we will profile HTTP Body content, disabled by default as it contains lots of data - profileHTTPBody : false - } - }, - // ColdBox Tracer Appender Messages - tracers : { enabled : true, expanded : false }, - // Request Collections Reporting - collections : { - // Enable tracking - enabled : false, - // Expanded panel or not - expanded : false, - // How many rows to dump for object collections - maxQueryRows : 50, - // How many levels to output on dumps for objects - maxDumpTop : 5 - }, - // CacheBox Reporting - cachebox : { enabled : true, expanded : false }, - // Modules Reporting - modules : { enabled : true, expanded : false }, - // Quick and QB Reporting - qb : { - enabled : false, - expanded : false, - // Log the binding parameters - logParams : true - }, - // cborm Reporting - cborm : { - enabled : false, - expanded : false, - // Log the binding parameters - logParams : false - }, - // Adobe ColdFusion SQL Collector - acfSql : { - enabled : true, - expanded : false, - // Log the binding parameters - logParams : true - }, - async : { enabled : true, expanded : false } - }; } } diff --git a/config/Router.cfc b/config/Router.cfc index bfa57f8..73d8166 100644 --- a/config/Router.cfc +++ b/config/Router.cfc @@ -1,17 +1,25 @@ +/** + * This is your application router. From here you can controll all the incoming routes to your application. + * + * https://coldbox.ortusbooks.com/the-basics/routing + */ component { function configure(){ - // Set Full Rewrites + /** + * -------------------------------------------------------------------------- + * Router Configuration Directives + * -------------------------------------------------------------------------- + * https://coldbox.ortusbooks.com/the-basics/routing/application-router#configuration-methods + */ setFullRewrites( true ); /** * -------------------------------------------------------------------------- * App Routes * -------------------------------------------------------------------------- - * * Here is where you can register the routes for your web application! * Go get Funky! - * */ // A nice healthcheck route example @@ -19,7 +27,9 @@ component { return "Ok!"; } ); - // Conventions based routing + // @app_routes@ + + // Conventions-Based Routing route( ":handler/:action?" ).end(); } diff --git a/config/Scheduler.cfc b/config/Scheduler.cfc index b74d2e3..c858ece 100644 --- a/config/Scheduler.cfc +++ b/config/Scheduler.cfc @@ -2,6 +2,7 @@ component { /** * Configure the ColdBox Scheduler + * https://coldbox.ortusbooks.com/digging-deeper/scheduled-tasks */ function configure(){ /** @@ -14,7 +15,6 @@ component { */ - /** * -------------------------------------------------------------------------- * Register Scheduled Tasks diff --git a/config/modules/cbdebugger.cfc b/config/modules/cbdebugger.cfc new file mode 100644 index 0000000..9ec0841 --- /dev/null +++ b/config/modules/cbdebugger.cfc @@ -0,0 +1,93 @@ +component { + + function configure(){ + return { + // This flag enables/disables the tracking of request data to our storage facilities + // To disable all tracking, turn this master key off + enabled : true, + // This setting controls if you will activate the debugger for visualizations ONLY + // The debugger will still track requests even in non debug mode. + debugMode : controller.getSetting( name = "environment", defaultValue = "production" ) == "development", + // The URL password to use to activate it on demand + debugPassword : "cb:null", + // This flag enables/disables the end of request debugger panel docked to the bottem of the page. + // If you disable i, then the only way to visualize the debugger is via the `/cbdebugger` endpoint + requestPanelDock : true, + // Request Tracker Options + requestTracker : { + // Store the request profilers in heap memory or in cachebox, default is memory + storage : "memory", + // Which cache region to store the profilers in + cacheName : "template", + // Track all cbdebugger events, by default this is off, turn on, when actually profiling yourself :) How Meta! + trackDebuggerEvents : false, + // Expand by default the tracker panel or not + expanded : false, + // Slow request threshold in milliseconds, if execution time is above it, we mark those transactions as red + slowExecutionThreshold : 1000, + // How many tracking profilers to keep in stack + maxProfilers : 50, + // If enabled, the debugger will monitor the creation time of CFC objects via WireBox + profileWireBoxObjectCreation : false, + // Profile model objects annotated with the `profile` annotation + profileObjects : false, + // If enabled, will trace the results of any methods that are being profiled + traceObjectResults : false, + // Profile Custom or Core interception points + profileInterceptions : false, + // By default all interception events are excluded, you must include what you want to profile + includedInterceptions : [], + // Control the execution timers + executionTimers : { + expanded : true, + // Slow transaction timers in milliseconds, if execution time of the timer is above it, we mark it + slowTimerThreshold : 250 + }, + // Control the coldbox info reporting + coldboxInfo : { expanded : false }, + // Control the http request reporting + httpRequest : { + expanded : false, + // If enabled, we will profile HTTP Body content, disabled by default as it contains lots of data + profileHTTPBody : false + }, + }, + // ColdBox Tracer Appender Messages + tracers : { enabled : true, expanded : false }, + // Request Collections Reporting + collections : { + // Enable tracking + enabled : false, + // Expanded panel or not + expanded : false, + // How many rows to dump for object collections + maxQueryRows : 50, + // How many levels to output on dumps for objects + maxDumpTop : 5 + }, + // CacheBox Reporting + cachebox : { enabled : true, expanded : false }, + // Modules Reporting + modules : { enabled : true, expanded : false }, + // Quick and QB Reporting + qb : { + enabled : false, + expanded : false, + // Log the binding parameters + logParams : true + }, + // cborm Reporting + cborm : { + enabled : false, + expanded : false, + // Log the binding parameters + logParams : false + }, + // Adobe ColdFusion SQL Collector + acfSql : { enabled : true, expanded : false, logParams : true }, + // Lucee SQL Collector + luceeSQL : { enabled : false, expanded : false, logParams : true }, + async : { enabled : true, expanded : false } + }; + } +} diff --git a/config/modules/cbswagger.cfc b/config/modules/cbswagger.cfc new file mode 100644 index 0000000..51999e5 --- /dev/null +++ b/config/modules/cbswagger.cfc @@ -0,0 +1,79 @@ +component { + + function configure(){ + return { + // The route prefix to search. Routes beginning with this prefix will be determined to be api routes + "routes" : [ "api/v6" ], + // Any routes to exclude + "excludeRoutes" : [], + // The default output format: json or yml + "defaultFormat" : "json", + // A convention route, relative to your app root, where request/response samples are stored ( e.g. resources/apidocs/responses/[module].[handler].[action].[HTTP Status Code].json ) + "samplesPath" : "resources/apidocs", + // Information about your API + "info" : { + // A title for your API + "title" : "Fluent API for SoapBox Twitter clone", + // A description of your API + "description" : "This Fluent API provides data the for SoapBox Twitter clone", + // A terms of service URL for your API + "termsOfService" : "", + // The contact email address + "contact" : { + "name" : "Gavin Pickin", + "url" : "https://www.ortussolutions.com", + "email" : "gavin@ortussolutions.com" + }, + // A url to the License of your API + "license" : { + "name" : "Apache 2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0.html" + }, + // The version of your API + "version" : "1.0.0" + }, + // Tags + "tags" : [], + // https://swagger.io/specification/#externalDocumentationObject + "externalDocs" : { + "description" : "Find more info here", + "url" : "https://blog.readme.io/an-example-filled-guide-to-swagger-3-2/" + }, + // https://swagger.io/specification/#serverObject + "servers" : [ + { + "url" : "http://127.0.0.1:60146", + "description" : "Local development" + } + ], + // An element to hold various schemas for the specification. + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject + "components" : { + // Define your security schemes here + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject + "securitySchemes" : { + // "ApiKeyAuth" : { + // "type" : "apiKey", + // "description" : "User your JWT as an Api Key for security", + // "name" : "x-api-key", + // "in" : "header" + // }, + // "bearerAuth" : { + // "type" : "http", + // "scheme" : "bearer", + // "bearerFormat" : "JWT" + // } + } + } + + // A default declaration of Security Requirement Objects to be used across the API. + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securityRequirementObject + // Only one of these requirements needs to be satisfied to authorize a request. + // Individual operations may set their own requirements with `@security` + // "security" : [ + // { "APIKey" : [] }, + // { "UserSecurity" : [] } + // ] + }; + } +} diff --git a/config/modules/mementifier.cfc b/config/modules/mementifier.cfc new file mode 100644 index 0000000..1cc8b44 --- /dev/null +++ b/config/modules/mementifier.cfc @@ -0,0 +1,26 @@ +component{ + + /** + * Mementifier settings: https://forgebox.io/view/mementifier + */ + function configure(){ + return { + // Turn on to use the ISO8601 date/time formatting on all processed date/time properites, else use the masks + iso8601Format : true, + // The default date mask to use for date properties + dateMask : "yyyy-MM-dd", + // The default time mask to use for date properties + timeMask : "HH:mm: ss", + // Enable orm auto default includes: If true and an object doesn't have any `memento` struct defined + // this module will create it with all properties and relationships it can find for the target entity + // leveraging the cborm module. + ormAutoIncludes : true, + // The default value for relationships/getters which return null + nullDefaultValue : "", + // Don't check for getters before invoking them + trustedGetters : false, + // If not empty, convert all date/times to the specific timezone + convertToTimezone : "UTC" + }; + } +} From 0b63c69e6591118670125df7204f485f04a13e29 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 13:25:45 +0200 Subject: [PATCH 62/75] more updates to new standards --- .../api/modules_app/v1/handlers/Echo.cfc | 8 - .../api/modules_app/v1/handlers/Rants.cfc | 8 +- .../api/modules_app/v1/models/RantService.cfc | 6 +- readme.md | 6 +- tests/Application.cfc | 80 +++++-- tests/index.cfm | 203 ++++++++++++------ tests/resources/BaseTest.cfc | 25 ++- tests/specs/integration/api-v1/EchoTests.cfc | 2 +- tests/specs/integration/api-v1/RantsTest.cfc | 138 +----------- 9 files changed, 228 insertions(+), 248 deletions(-) diff --git a/modules_app/api/modules_app/v1/handlers/Echo.cfc b/modules_app/api/modules_app/v1/handlers/Echo.cfc index f6d5be7..d451192 100644 --- a/modules_app/api/modules_app/v1/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v1/handlers/Echo.cfc @@ -3,14 +3,6 @@ */ component extends="coldbox.system.RestHandler" { - // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; - this.aroundHandler_except = ""; - // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} this.allowedMethods = {}; diff --git a/modules_app/api/modules_app/v1/handlers/Rants.cfc b/modules_app/api/modules_app/v1/handlers/Rants.cfc index 44a2ef6..9163bc3 100644 --- a/modules_app/api/modules_app/v1/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v1/handlers/Rants.cfc @@ -38,7 +38,7 @@ component extends="coldbox.system.RestHandler" { } var rant = rantService.getRant( rc.rantId ); - if ( rant.len() ) { + if ( rant.recordcount ) { prc.response.setData( queryGetRow( rant, 1 ) ); } else { prc.response.setError( true ); @@ -100,7 +100,7 @@ component extends="coldbox.system.RestHandler" { return; } var user = userService.get( rc.userId ) - if ( !user.len() ) { + if ( !user.recordcount ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); prc.response.addMessage( "User not found" ); @@ -148,7 +148,7 @@ component extends="coldbox.system.RestHandler" { return } var rant = rantService.getRant( rc.rantId ) - if ( !rant.len() ) { + if ( !rant.recordcount ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); prc.response.addMessage( "Rant not found" ); @@ -167,7 +167,7 @@ component extends="coldbox.system.RestHandler" { return; } var user = userService.get( rc.userId ) - if ( !user.len() ) { + if ( !user.recordcount ) { prc.response.setError( true ); prc.response.setStatusCode( 404 ); prc.response.addMessage( "User not found" ); diff --git a/modules_app/api/modules_app/v1/models/RantService.cfc b/modules_app/api/modules_app/v1/models/RantService.cfc index df6dac9..4743e88 100644 --- a/modules_app/api/modules_app/v1/models/RantService.cfc +++ b/modules_app/api/modules_app/v1/models/RantService.cfc @@ -44,7 +44,7 @@ component singleton accessors="true" { ", { rantId : newId, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + body : { value : "#body#", cfsqltype : "varchar" }, userId : arguments.userId }, { result : "local.result" } @@ -64,8 +64,8 @@ component singleton accessors="true" { ", { rantId : arguments.rantId, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } + body : { value : "#body#", cfsqltype : "varchar" }, + updatedDate : { value : "#now#", cfsqltype : "timestamp" } }, { result : "local.result" } ); diff --git a/readme.md b/readme.md index df31695..fec8dfc 100644 --- a/readme.md +++ b/readme.md @@ -29,7 +29,11 @@ migrate up Once you have your `.env`, your db loaded, and your `box.json` dependencies installed, you can start your server. -`box start` +```bash +# Adobe +run-script start:adobe +run-script start:lucee +``` ## What can you do in the app? diff --git a/tests/Application.cfc b/tests/Application.cfc index 73f8bc7..23c9697 100644 --- a/tests/Application.cfc +++ b/tests/Application.cfc @@ -1,27 +1,67 @@ /** -******************************************************************************** -Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.ortussolutions.com -******************************************************************************** -*/ -component{ + * Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + */ +component { // APPLICATION CFC PROPERTIES - this.name = "ColdBoxTestingSuite" & hash(getCurrentTemplatePath()); - this.sessionManagement = true; - this.sessionTimeout = createTimeSpan( 0, 0, 15, 0 ); - this.applicationTimeout = createTimeSpan( 0, 0, 15, 0 ); - this.setClientCookies = true; + this.name = "ColdBoxTestingSuite"; + this.sessionManagement = true; + this.setClientCookies = true; + this.sessionTimeout = createTimespan( 0, 0, 15, 0 ); + this.applicationTimeout = createTimespan( 0, 0, 15, 0 ); + this.whiteSpaceManagement = "smart"; this.datasource = "fluentAPI"; - + /** + * -------------------------------------------------------------------------- + * Location Mappings + * -------------------------------------------------------------------------- + * - cbApp : Quick reference to root application + * - coldbox : Where ColdBox library is installed + * - testbox : Where TestBox is installed + */ // Create testing mapping - this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); - // Map back to its root - rootPath = REReplaceNoCase( this.mappings[ "/tests" ], "tests(\\|/)", "" ); - this.mappings["/root"] = rootPath; + this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); + // The root application mapping + rootPath = reReplaceNoCase( this.mappings[ "/tests" ], "tests(\\|/)", "" ); + this.mappings[ "/root" ] = this.mappings[ "/cbapp" ] = rootPath; + this.mappings[ "/coldbox" ] = rootPath & "coldbox"; + this.mappings[ "/testbox" ] = rootPath & "testbox"; + + /** + * Fires on every test request. It builds a Virtual ColdBox application for you + * + * @targetPage The requested page + */ + public boolean function onRequestStart( targetPage ){ + // Set a high timeout for long running tests + setting requestTimeout ="9999"; + // New ColdBox Virtual Application Starter + request.coldBoxVirtualApp= new coldbox.system.testing.VirtualApp( appMapping = "/root" ); + + // If hitting the runner or specs, prep our virtual app + if ( getBaseTemplatePath().replace( expandPath( "/tests" ), "" ).reFindNoCase( "(runner|specs)" ) ) { + request.coldBoxVirtualApp.startup(); + } + + // Reload for fresh results + if ( structKeyExists( url, "fwreinit" ) ) { + if ( structKeyExists( server, "lucee" ) ) { + pagePoolClear(); + } + // ormReload(); + request.coldBoxVirtualApp.restart(); + } - public void function onRequestEnd() { - structDelete( application, "cbController" ); - structDelete( application, "wirebox" ); + return true; } -} \ No newline at end of file + + /** + * Fires when the testing requests end and the ColdBox application is shutdown + */ + public void function onRequestEnd( required targetPage ){ + request.coldBoxVirtualApp.shutdown(); + } + +} diff --git a/tests/index.cfm b/tests/index.cfm index 0ccfa80..485e396 100644 --- a/tests/index.cfm +++ b/tests/index.cfm @@ -1,53 +1,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - #testbox.init( directory=rootMapping & url.path ).run()# - -

Invalid incoming directory: #rootMapping & url.path#

-
- - -
- - - - - - - - - - - - - + + // No cf debugging + cfsetting( showdebugoutput="false" ); + // GLOBAL VARIABLES + ASSETS_DIR = expandPath( "/testbox/system/reports/assets" ); + TESTBOX_VERSION = new testBox.system.TestBox().getVersion(); + // TEST LOCATIONS -> UPDATE AS YOU SEE FIT + rootMapping = "/tests/specs"; + + // Local Variables + rootPath = expandPath( rootMapping ); + targetPath = rootPath; + + // Incoming Navigation + param name="url.path" default=""; + if( len( url.path ) ){ + targetPath = getCanonicalPath( rootpath & "/" & url.path ); + // Avoid traversals, reset to root + if( !findNoCase( rootpath, targetPath ) ){ + targetPath = rootpath; + } + } + + // Get the actual execution path + executePath = rootMapping & ( len( url.path ) ? "/#url.path#" : "/" ); + // Execute an incoming path + if( !isNull( url.action ) ){ + if( directoryExists( targetPath ) ){ + writeOutput( "#new testbox.system.TestBox( directory=executePath ).run()#" ); + } else { + writeOutput( "

Invalid Directory: #encodeForHTML( targetPath )#

" ); + } + abort; + } + + // Get the tests to navigate + qResults = directoryList( targetPath, false, "query", "", "name" ); + + // Calculate the back navigation path + if( len( url.path ) ){ + backPath = url.path.listToArray( "/\" ); + backPath.pop(); + backPath = backPath.toList( "/" ); + } +
- + TestBox Browser @@ -56,51 +56,126 @@ - -
+ +

- v#testbox.getVersion()# + v#TESTBOX_VERSION#
- + + + +
+
+ + +
+
+

Availble Test Runners:

+

+ Below is a listing of the runners matching the "runner*.(cfm|bxm)" pattern. +

+ + + + + class="btn btn-success btn-sm my-1 mx-1" + + class="btn btn-info btn-sm my-1 mx-1" + + > + #runners.name# + +
+ +

TestBox Test Browser:

- Below is a listing of the files and folders starting from your root #rootPath#. You can click on individual tests in order to execute them + Below is a listing of the files and folders starting from your root #rootMapping#. You can click on individual tests in order to execute them or click on the Run All button on your left and it will execute a directory runner from the visible folder.

- Contents: #executePath# - -

+ #targetPath.replace( rootPath, "" )# + + + + + + +
+
+ - + + - - ✚ #qResults.name#
- - target="_blank"
>#qResults.name#
- - target="_blank"
>#qResults.name#
- - #qResults.name#
+ + &##x271A; #qResults.name# + +
+ + + #qResults.name# + +
+ + + data-bx="true" + class="btn btn-success btn-sm my-1" + + data-bx="false" + class="btn btn-info btn-sm my-1" +
+ href="#executePath & "/" & qResults.name#?method=runRemote" + target="_blank" + > + #qResults.name# + +
@@ -112,4 +187,4 @@ - \ No newline at end of file + diff --git a/tests/resources/BaseTest.cfc b/tests/resources/BaseTest.cfc index e3b153a..ef117c5 100644 --- a/tests/resources/BaseTest.cfc +++ b/tests/resources/BaseTest.cfc @@ -11,8 +11,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { function beforeAll(){ super.beforeAll(); - var lengthTest = - addMatchers( { toHaveStatusCode : function( expectation, args = {} ) { // handle both positional and named arguments @@ -126,7 +124,20 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { return false; } try{ - var length = expectation.actual.len(); + var length = 0; + if ( isSimpleValue( expectation.actual ) ) { + length = len( expectation.actual ); + } + if ( isArray( expectation.actual ) ) { + length = arrayLen( expectation.actual ); + } + if ( isStruct( expectation.actual ) ) { + length = structCount( expectation.actual ); + } + if ( isQuery( expectation.actual ) ) { + length = expectation.actual.recordcount; + } + } catch ( any e ){ expectation.message = "The length of the Item could not be found"; return false; @@ -160,14 +171,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { super.afterAll(); } - /** - * Custom test reset - */ - function reset(){ - structDelete( application, "wirebox" ); - structDelete( application, "cbController" ); - } - /** * Rollback all testing, called by TestBox for me * diff --git a/tests/specs/integration/api-v1/EchoTests.cfc b/tests/specs/integration/api-v1/EchoTests.cfc index 96f0637..95c7d1b 100644 --- a/tests/specs/integration/api-v1/EchoTests.cfc +++ b/tests/specs/integration/api-v1/EchoTests.cfc @@ -77,7 +77,7 @@ component extends="coldbox.system.testing.BaseTestCase" { var event = this.request( "/api/v1/echo/bogus" ); var response = event.getPrivateValue( "response" ); expect( response.getError() ).tobeTrue(); - expect( response.getStatusCode() ).toBe( 405 ); + expect( response.getStatusCode() ).toBe( 404 ); } ); } ); } diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index 8b28e7d..e775b39 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -13,17 +13,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a list of Rants", function(){ var event = get( "/api/v1/rants/list" ); var returnedJSON = event.getRenderData().data; - - expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); - // expect( structKeyExists( returnedJSON, "error" ) ).toBe( true ); - // expect( returnedJSON ).toHaveKey( "error" ); - // expect( returnedJSON ).toHaveKey( "errors" ); - // expect( returnedJSON ).toHaveKeyWithCase( "ERROR" ); - // expect( returnedJSON ).toHaveKeyWithCase( "errors" ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + //debug( returnedJSON ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON.data ).toBeQuery(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); } ); @@ -36,13 +27,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v1/rants/view" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event.getStatusCode() ).toBe( 412 ); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -51,12 +37,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v1/rants/view?rantID=abc" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -65,12 +47,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 404 error", function(){ var event = get( "/api/v1/rants/view?rantID=#createUUID()#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); } ); @@ -80,15 +58,11 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v1/rants/view?rantID=#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + //debug( returnedJSON ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatusCode( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); } ); @@ -101,12 +75,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (create): GET" ); } ); } ); @@ -115,12 +85,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body is required" ); } ); } ); @@ -129,12 +95,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/create", { "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body cannot be empty" ); } ); } ); @@ -143,12 +105,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/create", { "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID is required" ); } ); } ); @@ -157,12 +115,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -171,12 +125,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -188,12 +138,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : "#createUUID()#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -209,16 +155,10 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); expect( returnedJSON.data.rantID ).toBeGT( 7 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); } ); } ); @@ -231,12 +171,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/save" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body is required" ); } ); } ); @@ -245,12 +181,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/save", { "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body cannot be empty" ); } ); } ); @@ -259,12 +191,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/save", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -273,12 +201,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -287,12 +211,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -304,12 +224,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "rantID" : "#createUUID()#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -322,12 +238,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "rantID" : "#testRant.id#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID is required" ); } ); } ); @@ -344,12 +256,8 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -366,12 +274,8 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -388,12 +292,8 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -410,13 +310,8 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); } ); } ); @@ -429,12 +324,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): GET" ); } ); } ); @@ -443,12 +334,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): POST" ); @@ -459,12 +346,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = delete( "/api/v1/rants/delete", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -473,12 +356,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = delete( "/api/v1/rants/delete", { "rantID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -487,12 +366,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = delete( "/api/v1/rants/delete", { "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -501,12 +376,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 404 error", function(){ var event = delete( "/api/v1/rants/delete", { "rantID" : "#createUUID()#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatusCode( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -521,13 +392,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v1/rants/delete", { "rantID" : testRantId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); - expect( returnedJSON.messages ).toBeArray(); - expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); } ); From d22c7b3d0574ad887d99bb9a9fd40d92fb464fa1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 13:41:26 +0200 Subject: [PATCH 63/75] v1 finalized --- box.json | 3 +- config/modules/cbdebugger.cfc | 2 +- server-adobe.json | 2 +- tests/index.cfm | 34 +++++++++++--------- tests/specs/integration/api-v1/RantsTest.cfc | 6 ++-- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/box.json b/box.json index 747b704..7b04013 100644 --- a/box.json +++ b/box.json @@ -50,8 +50,9 @@ "runner":"http://localhost:60146/tests/runner.cfm" }, "scripts":{ + "start:adobe":"server start serverConfigFile=server-adobe.json --force", + "start:boxlang":"server start serverConfigFile=server-boxlang.json --force", "start:lucee":"server start serverConfigFile=server-lucee.json --force", - "start:adobe":"server start serverConfigFile=server.json --force", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", diff --git a/config/modules/cbdebugger.cfc b/config/modules/cbdebugger.cfc index 9ec0841..e8173d1 100644 --- a/config/modules/cbdebugger.cfc +++ b/config/modules/cbdebugger.cfc @@ -50,7 +50,7 @@ component { expanded : false, // If enabled, we will profile HTTP Body content, disabled by default as it contains lots of data profileHTTPBody : false - }, + } }, // ColdBox Tracer Appender Messages tracers : { enabled : true, expanded : false }, diff --git a/server-adobe.json b/server-adobe.json index b00c5ed..7ce0379 100644 --- a/server-adobe.json +++ b/server-adobe.json @@ -12,7 +12,7 @@ "enable":"true" } }, - "cfconfig":{ + "cfconfig":{ "file":".cfconfig.json" }, "scripts":{ diff --git a/tests/index.cfm b/tests/index.cfm index 485e396..1ad8dd4 100644 --- a/tests/index.cfm +++ b/tests/index.cfm @@ -5,7 +5,7 @@ ASSETS_DIR = expandPath( "/testbox/system/reports/assets" ); TESTBOX_VERSION = new testBox.system.TestBox().getVersion(); // TEST LOCATIONS -> UPDATE AS YOU SEE FIT - rootMapping = "/tests/specs"; + rootMapping = "/tests"; // Local Variables rootPath = expandPath( rootMapping ); @@ -90,20 +90,24 @@ Below is a listing of the runners matching the "runner*.(cfm|bxm)" pattern.

- - - - class="btn btn-success btn-sm my-1 mx-1" - - class="btn btn-info btn-sm my-1 mx-1" - - > - #runners.name# - - + + +

No runners found in this directory

+ + + + class="btn btn-success btn-sm my-1 mx-1" + + class="btn btn-info btn-sm my-1 mx-1" +
+ > + #runners.name# + + +
diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index e775b39..831ade6 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -61,7 +61,7 @@ component extends="tests.resources.BaseTest" { //debug( returnedJSON ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatusCode( 200 ); - expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); + expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -157,8 +157,8 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantID" ); - expect( returnedJSON.data.rantID ).toBeGT( 7 ); + expect( returnedJSON.data ).toHaveKey( "rantID" ); + expect( returnedJSON.data.rantID ).notToBeEmpty(); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); } ); } ); From 8b48d154083967b05ca695077394caeb40a01f76 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 13:50:08 +0200 Subject: [PATCH 64/75] leveraging new matchers in ColdBox --- server-boxlang.json | 13 +++++ tests/resources/BaseTest.cfc | 36 ------------- tests/specs/integration/api-v1/RantsTest.cfc | 54 ++++++++++---------- tests/specs/integration/api-v2/RantsTest.cfc | 50 +++++++++--------- tests/specs/integration/api-v3/RantsTest.cfc | 38 +++++++------- tests/specs/integration/api-v4/RantsTest.cfc | 38 +++++++------- tests/specs/integration/api-v5/RantsTest.cfc | 36 ++++++------- tests/specs/integration/api-v6/RantsTest.cfc | 36 ++++++------- 8 files changed, 139 insertions(+), 162 deletions(-) diff --git a/server-boxlang.json b/server-boxlang.json index a8ee0ef..54e682d 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -11,5 +11,18 @@ "rewrites":{ "enable":"true" } + }, + "JVM":{ + "javaVersion":"openjdk21_jdk", + "args": "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" + }, + "cfconfig":{ + "file":".cfconfig.json" + }, + "env":{ + "BOXLANG_DEBUG":true + }, + "scripts":{ + "onServerInitialInstall":"install bx-compat,bx-unsafe-evaluate,bx-mysql" } } diff --git a/tests/resources/BaseTest.cfc b/tests/resources/BaseTest.cfc index ef117c5..6963e35 100644 --- a/tests/resources/BaseTest.cfc +++ b/tests/resources/BaseTest.cfc @@ -12,40 +12,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { super.beforeAll(); addMatchers( { - toHaveStatusCode : function( expectation, args = {} ) { - // handle both positional and named arguments - param args.statusCode = ""; - if ( structKeyExists( args, 1 ) ) { - args.statusCode = args[ 1 ]; - } - param args.message = ""; - if ( structKeyExists( args, 2 ) ) { - args.message = args[ 2 ]; - } - - if ( args.statusCode == "" ) { - expectation.message = "No status code provided."; - return false; - } - - try { - var statusCode = expectation.actual.getStatusCode(); - } - catch ( any e ) { - expectation.message = "[#expecation.actual#] does not have a getStatusCode method."; - debug( expectation.actual.getResponse() ); - return false; - } - - if ( statusCode != args.statusCode ) { - expectation.message = "#args.message#. Received incorrect status code. Expected [#args.statusCode#]. Received [#statusCode#]."; - debug( expectation.actual.getResponse() ); - return false; - } - - return true; - }, - toHaveKeyWithCase : function( expectation, args = {} ) { // handle both positional and named arguments param args.key = ""; @@ -95,8 +61,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { return arguments.lengthTest( expectation, args ); } } ); - - getWireBox().autowire( this ); } /** diff --git a/tests/specs/integration/api-v1/RantsTest.cfc b/tests/specs/integration/api-v1/RantsTest.cfc index 831ade6..a289f91 100644 --- a/tests/specs/integration/api-v1/RantsTest.cfc +++ b/tests/specs/integration/api-v1/RantsTest.cfc @@ -28,7 +28,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v1/rants/view" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -38,7 +38,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v1/rants/view?rantID=abc" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -48,7 +48,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v1/rants/view?rantID=#createUUID()#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); } ); @@ -60,7 +60,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; //debug( returnedJSON ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); expect( returnedJSON.messages ).toHaveLength( 0 ); @@ -76,7 +76,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (create): GET" ); } ); } ); @@ -86,7 +86,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/create" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body is required" ); } ); } ); @@ -96,7 +96,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/create", { "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body cannot be empty" ); } ); } ); @@ -106,7 +106,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/create", { "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID is required" ); } ); } ); @@ -116,7 +116,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -126,7 +126,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/create", { "body" : "xsxswxws", "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -139,7 +139,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -172,7 +172,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/save" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body is required" ); } ); } ); @@ -182,7 +182,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/save", { "body" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant body cannot be empty" ); } ); } ); @@ -192,7 +192,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/save", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -202,7 +202,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -212,7 +212,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/save", { "body" : "abc", "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -225,7 +225,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); @@ -239,7 +239,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID is required" ); } ); } ); @@ -257,7 +257,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -275,7 +275,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "userID must be a UUID" ); } ); } ); @@ -293,7 +293,7 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); } ); @@ -325,7 +325,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): GET" ); } ); } ); @@ -335,7 +335,7 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v1/rants/delete" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): POST" ); @@ -347,7 +347,7 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v1/rants/delete", { "body" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID is required" ); } ); } ); @@ -357,7 +357,7 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v1/rants/delete", { "rantID" : "" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -367,7 +367,7 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v1/rants/delete", { "rantID" : "abc" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON.messages[ 1 ] ).toBe( "rantID must be a UUID" ); } ); } ); @@ -377,7 +377,7 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v1/rants/delete", { "rantID" : "#createUUID()#" } ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); } ); diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 72e4883..7d767a8 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -33,7 +33,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -50,7 +50,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -65,7 +65,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); @@ -86,7 +86,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -100,7 +100,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -114,7 +114,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -128,7 +128,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -144,7 +144,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -158,7 +158,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -175,7 +175,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -218,7 +218,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -232,7 +232,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -246,7 +246,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -261,7 +261,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -277,7 +277,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -294,7 +294,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -311,7 +311,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -330,7 +330,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -347,7 +347,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -386,7 +386,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -401,7 +401,7 @@ component extends="tests.resources.BaseTest" { debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -418,7 +418,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 405 ); + expect( event ).toHaveStatus( 405 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -435,7 +435,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -450,7 +450,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 412 ); + expect( event ).toHaveStatus( 412 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -468,7 +468,7 @@ component extends="tests.resources.BaseTest" { debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 2d5f99b..33391ce 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -32,7 +32,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -46,7 +46,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -61,7 +61,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); @@ -92,7 +92,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -105,7 +105,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -118,7 +118,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -131,7 +131,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -144,7 +144,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -158,7 +158,7 @@ component extends="tests.resources.BaseTest" { debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -218,7 +218,7 @@ component extends="tests.resources.BaseTest" { debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -232,7 +232,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -246,7 +246,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -260,7 +260,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -274,7 +274,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -291,7 +291,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -308,7 +308,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -325,7 +325,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -396,7 +396,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -410,7 +410,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 552ef52..75e903a 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -33,7 +33,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -47,7 +47,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -61,7 +61,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); @@ -92,7 +92,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -105,7 +105,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -118,7 +118,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -131,7 +131,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -144,7 +144,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -157,7 +157,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -215,7 +215,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -229,7 +229,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -243,7 +243,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -257,7 +257,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -274,7 +274,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -292,7 +292,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -309,7 +309,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -326,7 +326,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -397,7 +397,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -411,7 +411,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 7aad357..98a3139 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -33,7 +33,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -48,7 +48,7 @@ component extends="tests.resources.BaseTest" { // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -62,7 +62,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); @@ -92,7 +92,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -105,7 +105,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -118,7 +118,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -131,7 +131,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -144,7 +144,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -157,7 +157,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -215,7 +215,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -229,7 +229,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -243,7 +243,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -260,7 +260,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -274,7 +274,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -291,7 +291,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -305,7 +305,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -376,7 +376,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -390,7 +390,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index f047fd7..9b85357 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -33,7 +33,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -48,7 +48,7 @@ component extends="tests.resources.BaseTest" { // debug( returnedJSON ); expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -62,7 +62,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( event ).toHaveStatusCode( 200 ); + expect( event ).toHaveStatus( 200 ); expect( returnedJSON ).toHaveKeyWithCase( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); @@ -92,7 +92,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -105,7 +105,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -118,7 +118,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -131,7 +131,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -144,7 +144,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -157,7 +157,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -215,7 +215,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -229,7 +229,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -243,7 +243,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -260,7 +260,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -274,7 +274,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -291,7 +291,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 400 ); + expect( event ).toHaveStatus( 400 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -308,7 +308,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); @@ -378,7 +378,7 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); } ); } ); @@ -389,7 +389,7 @@ component extends="tests.resources.BaseTest" { var returnedJSON = event.getRenderData().data; expect( returnedJSON ).toHaveKeyWithCase( "error" ); expect( returnedJSON.error ).toBeTrue(); - expect( event ).toHaveStatusCode( 404 ); + expect( event ).toHaveStatus( 404 ); expect( returnedJSON ).toHaveKeyWithCase( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); From 15f607cb251919fd44a4866f5028e8a9db23a5da Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 14:28:17 +0200 Subject: [PATCH 65/75] use withKey --- tests/resources/BaseTest.cfc | 29 ----- tests/specs/integration/api-v2/RantsTest.cfc | 128 +++++++++---------- tests/specs/integration/api-v3/RantsTest.cfc | 104 +++++++-------- tests/specs/integration/api-v4/RantsTest.cfc | 104 +++++++-------- tests/specs/integration/api-v5/RantsTest.cfc | 100 +++++++-------- tests/specs/integration/api-v6/RantsTest.cfc | 96 +++++++------- 6 files changed, 266 insertions(+), 295 deletions(-) diff --git a/tests/resources/BaseTest.cfc b/tests/resources/BaseTest.cfc index 6963e35..8d60eef 100644 --- a/tests/resources/BaseTest.cfc +++ b/tests/resources/BaseTest.cfc @@ -12,35 +12,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { super.beforeAll(); addMatchers( { - toHaveKeyWithCase : function( expectation, args = {} ) { - // handle both positional and named arguments - param args.key = ""; - if ( structKeyExists( args, 1 ) ) { - args.key = args[ 1 ]; - } - param args.message = ""; - if ( structKeyExists( args, 2 ) ) { - args.message = args[ 2 ]; - } - - if ( args.key == "" ) { - expectation.message = "No Key Provided."; - return false; - } - - if( !listFind( expectation.actual.keyList(), args.key ) ){ - if( listFindNoCase( expectation.actual.keyList(), args.key ) ){ - expectation.message = "The key(s) [#args.key#] does exist in the target object, but the Case is incorrect. Found keys are [#structKeyArray( expectation.actual ).toString()#]"; - } else { - expectation.message = "The key(s) [#args.key#] does not exist in the target object, with or without case sensitivity. Found keys are [#structKeyArray( expectation.actual ).toString()#]"; - } - debug( expectation.actual ); - return false; - } - - return true; - }, - toHaveLengthGT : function( expectation, args = {}, lengthTest=variables.lengthTest ) { args[ "operator" ] = "GT"; return arguments.lengthTest( expectation, args ); diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index 7d767a8..f77ce24 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -14,9 +14,9 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v2/rants" ); var returnedJSON = event.getRenderData().data; expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,10 +31,10 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -48,10 +48,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); @@ -63,14 +63,14 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v2/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); + expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -84,10 +84,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/create" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (create): GET" ); @@ -98,10 +98,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); @@ -112,10 +112,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); @@ -126,10 +126,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -142,10 +142,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); @@ -156,10 +156,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); @@ -173,10 +173,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); @@ -191,13 +191,13 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : "#testUserId#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); @@ -216,10 +216,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/#testRant.id#/save" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (save): GET" ); @@ -230,10 +230,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); @@ -244,10 +244,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); @@ -259,10 +259,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v2/rants/#rantID#/save", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -275,10 +275,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); @@ -292,10 +292,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); @@ -309,10 +309,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -328,10 +328,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); @@ -345,10 +345,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); @@ -365,11 +365,11 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); @@ -384,10 +384,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/a/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): GET" ); @@ -399,10 +399,10 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -416,10 +416,10 @@ component extends="tests.resources.BaseTest" { var rantID = ""; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -433,10 +433,10 @@ component extends="tests.resources.BaseTest" { var rantID = " "; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'RANTID' value is required" ); @@ -448,10 +448,10 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( @@ -466,10 +466,10 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); @@ -486,11 +486,11 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/#testRantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 33391ce..31088b3 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -13,9 +13,9 @@ component extends="tests.resources.BaseTest" { then( "I will get a list of Rants", function(){ var event = get( "/api/v3/rants" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -30,10 +30,10 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -44,10 +44,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); @@ -59,14 +59,14 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v3/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "ID" ); + expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -90,10 +90,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -103,10 +103,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -116,10 +116,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -129,10 +129,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -142,10 +142,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -156,10 +156,10 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); @@ -171,13 +171,13 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); @@ -216,10 +216,10 @@ component extends="tests.resources.BaseTest" { var event = put( "/api/v3/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -230,10 +230,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -244,10 +244,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -258,10 +258,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -272,10 +272,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -289,10 +289,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -306,10 +306,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); @@ -323,10 +323,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); @@ -341,11 +341,11 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); @@ -394,10 +394,10 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -408,10 +408,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); @@ -428,11 +428,11 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v3/rants/#testRantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 75e903a..7de76a3 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -14,9 +14,9 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v4/rants" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,10 +31,10 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -45,10 +45,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -59,14 +59,14 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v4/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); expect( returnedJSON.data.rantId ).toBe( testRantId ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -90,10 +90,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -103,10 +103,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -116,10 +116,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -129,10 +129,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -142,10 +142,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -155,10 +155,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 404 error", function(){ var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -169,13 +169,13 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); @@ -213,10 +213,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -227,10 +227,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -241,10 +241,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -255,10 +255,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -272,10 +272,10 @@ component extends="tests.resources.BaseTest" { { "userID" : testRant.userId, "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -290,10 +290,10 @@ component extends="tests.resources.BaseTest" { { "userID" : testRant.userId, "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -307,10 +307,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -324,10 +324,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -342,11 +342,11 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); @@ -395,10 +395,10 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -409,10 +409,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -431,11 +431,11 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v4/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); diff --git a/tests/specs/integration/api-v5/RantsTest.cfc b/tests/specs/integration/api-v5/RantsTest.cfc index 98a3139..da9a468 100644 --- a/tests/specs/integration/api-v5/RantsTest.cfc +++ b/tests/specs/integration/api-v5/RantsTest.cfc @@ -14,9 +14,9 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v5/rants" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,10 +31,10 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -46,10 +46,10 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -60,13 +60,13 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v5/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "id" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -90,10 +90,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -103,10 +103,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -116,10 +116,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -129,10 +129,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -142,10 +142,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -155,10 +155,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -169,13 +169,13 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v5/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "id" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "id" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); @@ -213,10 +213,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -227,10 +227,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -241,10 +241,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v5/rants/#testRant.id#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -258,10 +258,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -272,10 +272,10 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = put( "/api/v5/rants/#rantID#", { "userID" : "1", "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -289,10 +289,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : "1" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -303,10 +303,10 @@ component extends="tests.resources.BaseTest" { var rantID = "1"; var event = put( "/api/v5/rants/#rantID#", { "userID" : "5", "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -321,11 +321,11 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); @@ -374,10 +374,10 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -388,10 +388,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -410,11 +410,11 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v5/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); diff --git a/tests/specs/integration/api-v6/RantsTest.cfc b/tests/specs/integration/api-v6/RantsTest.cfc index 9b85357..f3ff955 100644 --- a/tests/specs/integration/api-v6/RantsTest.cfc +++ b/tests/specs/integration/api-v6/RantsTest.cfc @@ -14,9 +14,9 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v6/rants" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,10 +31,10 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v5/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -46,10 +46,10 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -60,13 +60,13 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v6/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); @@ -90,10 +90,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -103,10 +103,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -116,10 +116,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -129,10 +129,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -142,10 +142,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -155,10 +155,10 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -169,13 +169,13 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v6/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); + expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); - expect( returnedJSON.data ).toHaveKeyWithCase( "rantId" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON.data ).toHaveKey( "rantId" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); @@ -213,10 +213,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v6/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -227,10 +227,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v6/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -241,10 +241,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v6/rants/#testRant.id#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -258,10 +258,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -272,10 +272,10 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v5/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -289,10 +289,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -306,10 +306,10 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -324,11 +324,11 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); @@ -387,10 +387,10 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v6/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); @@ -409,11 +409,11 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v6/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKeyWithCase( "error" ); + expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKeyWithCase( "data" ); - expect( returnedJSON ).toHaveKeyWithCase( "messages" ); + expect( returnedJSON ).toHaveKey( "data" ); + expect( returnedJSON ).toHaveKey( "messages" ); expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); From 6c32632150fed2aac95ffcf9dd07296f95ed56dd Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 14:41:21 +0200 Subject: [PATCH 66/75] v2 certified --- .../api/modules_app/v2/handlers/Echo.cfc | 8 -- tests/specs/integration/api-v2/RantsTest.cfc | 90 ------------------- 2 files changed, 98 deletions(-) diff --git a/modules_app/api/modules_app/v2/handlers/Echo.cfc b/modules_app/api/modules_app/v2/handlers/Echo.cfc index 9e9f6d9..70e9fe2 100644 --- a/modules_app/api/modules_app/v2/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v2/handlers/Echo.cfc @@ -3,14 +3,6 @@ */ component extends="coldbox.system.RestHandler" { - // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; - this.aroundHandler_except = ""; - // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} this.allowedMethods = {}; diff --git a/tests/specs/integration/api-v2/RantsTest.cfc b/tests/specs/integration/api-v2/RantsTest.cfc index f77ce24..1addabc 100644 --- a/tests/specs/integration/api-v2/RantsTest.cfc +++ b/tests/specs/integration/api-v2/RantsTest.cfc @@ -14,9 +14,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v2/rants" ); var returnedJSON = event.getRenderData().data; expect( structKeyExists( returnedJSON, "error" ) ).toBeTrue(); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,11 +29,8 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'RANTID' has an invalid type, expected type is uuid" @@ -48,11 +43,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v2/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toMatch( "Rant not found" ); } ); @@ -63,15 +55,11 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v2/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); } ); @@ -84,11 +72,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/create" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (create): GET" ); } ); @@ -98,11 +83,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); @@ -112,11 +94,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); @@ -126,11 +105,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' has an invalid type, expected type is uuid" @@ -142,11 +118,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); @@ -156,11 +129,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = post( "/api/v2/rants/create", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); @@ -173,11 +143,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); @@ -191,14 +158,10 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : "#testUserId#" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "rantId" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); } ); @@ -216,11 +179,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/#testRant.id#/save" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (save): GET" ); } ); @@ -230,11 +190,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); @@ -244,11 +201,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' value is required" ); } ); @@ -259,11 +213,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v2/rants/#rantID#/save", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'USERID' has an invalid type, expected type is uuid" @@ -275,11 +226,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = put( "/api/v2/rants/#testRant.id#/save", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); @@ -292,11 +240,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'BODY' value is required" ); } ); @@ -309,11 +254,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'RANTID' has an invalid type, expected type is uuid" @@ -328,11 +270,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "User not found" ); } ); @@ -345,11 +284,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); @@ -365,12 +301,8 @@ component extends="tests.resources.BaseTest" { } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); } ); @@ -384,11 +316,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 412 error", function(){ var event = get( "/api/v2/rants/a/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (delete): GET" ); } ); @@ -399,11 +328,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (view): DELETE" @@ -416,11 +342,8 @@ component extends="tests.resources.BaseTest" { var rantID = ""; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 405 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "InvalidHTTPMethod Execution of (view): DELETE" @@ -433,11 +356,8 @@ component extends="tests.resources.BaseTest" { var rantID = " "; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'RANTID' value is required" ); } ); @@ -448,11 +368,8 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 412 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "The 'RANTID' has an invalid type, expected type is uuid" @@ -466,11 +383,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/#rantID#/delete" ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant not found" ); } ); @@ -486,12 +400,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v2/rants/#testRantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); From de6039a12340fcf95f73891b0a82c385228cfb7e Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 15:51:04 +0200 Subject: [PATCH 67/75] v3 done --- .../api/modules_app/v2/models/RantService.cfc | 6 +- .../api/modules_app/v3/handlers/Echo.cfc | 8 --- .../api/modules_app/v3/handlers/Rants.cfc | 1 - .../api/modules_app/v3/models/RantService.cfc | 6 +- .../api/modules_app/v4/models/RantService.cfc | 6 +- .../api/modules_app/v5/models/RantService.cfc | 6 +- .../api/modules_app/v6/models/RantService.cfc | 6 +- tests/specs/integration/api-v3/RantsTest.cfc | 72 ------------------- 8 files changed, 15 insertions(+), 96 deletions(-) diff --git a/modules_app/api/modules_app/v2/models/RantService.cfc b/modules_app/api/modules_app/v2/models/RantService.cfc index 5175fec..a92fa18 100644 --- a/modules_app/api/modules_app/v2/models/RantService.cfc +++ b/modules_app/api/modules_app/v2/models/RantService.cfc @@ -51,7 +51,7 @@ component singleton accessors="true" { ", { rantId : newKey, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + body : { value : "#body#", cfsqltype : "longvarchar" }, userId : arguments.userId }, { result : "local.result" } @@ -71,8 +71,8 @@ component singleton accessors="true" { ", { rantId : arguments.rantId, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } + body : { value : "#body#", cfsqltype : "longvarchar" }, + updatedDate : { value : "#now#", cfsqltype : "timestamp" } }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v3/handlers/Echo.cfc b/modules_app/api/modules_app/v3/handlers/Echo.cfc index 1488f19..4c3a4ce 100644 --- a/modules_app/api/modules_app/v3/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v3/handlers/Echo.cfc @@ -3,14 +3,6 @@ */ component extends="coldbox.system.RestHandler" { - // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; - this.aroundHandler_except = ""; - // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} this.allowedMethods = {}; diff --git a/modules_app/api/modules_app/v3/handlers/Rants.cfc b/modules_app/api/modules_app/v3/handlers/Rants.cfc index 91b68fa..d5f052a 100644 --- a/modules_app/api/modules_app/v3/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v3/handlers/Rants.cfc @@ -56,7 +56,6 @@ component extends="coldbox.system.RestHandler" { /** * Updates an Existing Rant - * */ function update( event, rc, prc ){ validateOrFail( diff --git a/modules_app/api/modules_app/v3/models/RantService.cfc b/modules_app/api/modules_app/v3/models/RantService.cfc index 29228cd..2142d6b 100644 --- a/modules_app/api/modules_app/v3/models/RantService.cfc +++ b/modules_app/api/modules_app/v3/models/RantService.cfc @@ -39,7 +39,7 @@ component ", { rantId : newKey, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, + body : { value : "#body#", cfsqltype : "varchar" }, userId : arguments.userId }, { result : "local.result" } @@ -59,8 +59,8 @@ component ", { rantId : arguments.rantId, - body : { value : "#body#", cfsqltype : "cf_sql_longvarchar" }, - updatedDate : { value : "#now#", cfsqltype : "cf_sql_timestamp" } + body : { value : "#body#", cfsqltype : "varchar" }, + updatedDate : { value : "#now#", cfsqltype : "timestamp" } }, { result : "local.result" } ); diff --git a/modules_app/api/modules_app/v4/models/RantService.cfc b/modules_app/api/modules_app/v4/models/RantService.cfc index a11ddf1..20e6af8 100644 --- a/modules_app/api/modules_app/v4/models/RantService.cfc +++ b/modules_app/api/modules_app/v4/models/RantService.cfc @@ -56,7 +56,7 @@ component rantId : arguments.rant.getId(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, userId : arguments.rant.getuserId() } @@ -77,11 +77,11 @@ component rantId : arguments.rant.getID(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, updatedDate : { value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" + cfsqltype : "timestamp" } } ); diff --git a/modules_app/api/modules_app/v5/models/RantService.cfc b/modules_app/api/modules_app/v5/models/RantService.cfc index 8486ce0..3e4aa7c 100644 --- a/modules_app/api/modules_app/v5/models/RantService.cfc +++ b/modules_app/api/modules_app/v5/models/RantService.cfc @@ -50,7 +50,7 @@ component rantId : arguments.rant.getId(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, userId : arguments.rant.getuserId() } @@ -71,11 +71,11 @@ component rantId : arguments.rant.getID(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, updatedDate : { value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" + cfsqltype : "timestamp" } } ); diff --git a/modules_app/api/modules_app/v6/models/RantService.cfc b/modules_app/api/modules_app/v6/models/RantService.cfc index 3aa2547..a71e387 100644 --- a/modules_app/api/modules_app/v6/models/RantService.cfc +++ b/modules_app/api/modules_app/v6/models/RantService.cfc @@ -50,7 +50,7 @@ component rantId : arguments.rant.getId(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, userId : arguments.rant.getuserId() } @@ -71,11 +71,11 @@ component rantId : arguments.rant.getID(), body : { value : "#arguments.rant.getBody()#", - cfsqltype : "cf_sql_longvarchar" + cfsqltype : "longvarchar" }, updatedDate : { value : "#arguments.rant.getUpdatedDate()#", - cfsqltype : "cf_sql_timestamp" + cfsqltype : "timestamp" } } ); diff --git a/tests/specs/integration/api-v3/RantsTest.cfc b/tests/specs/integration/api-v3/RantsTest.cfc index 31088b3..12ea126 100644 --- a/tests/specs/integration/api-v3/RantsTest.cfc +++ b/tests/specs/integration/api-v3/RantsTest.cfc @@ -13,9 +13,7 @@ component extends="tests.resources.BaseTest" { then( "I will get a list of Rants", function(){ var event = get( "/api/v3/rants" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -30,11 +28,8 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -44,11 +39,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); @@ -59,15 +51,11 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v3/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "ID" ); expect( returnedJSON.data.id ).toBe( testRantId ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); } ); @@ -90,11 +78,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -103,11 +88,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -116,11 +98,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -129,11 +108,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "5" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -142,11 +118,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v3/rants", { "userID" : "5", "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -156,11 +129,8 @@ component extends="tests.resources.BaseTest" { var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); } ); @@ -171,14 +141,10 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v3/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "rantId" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); } ); @@ -216,11 +182,8 @@ component extends="tests.resources.BaseTest" { var event = put( "/api/v3/rants/#rantID#", {} ); var returnedJSON = event.getRenderData().data; debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -230,11 +193,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -244,11 +204,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -258,11 +215,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -272,11 +226,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = put( "/api/v3/rants/#rantID#", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -289,11 +240,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -306,11 +254,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "user not found" ); } ); @@ -323,11 +268,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); @@ -341,12 +283,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); } ); @@ -394,11 +332,8 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -408,11 +343,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v3/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toInclude( "rant not found" ); } ); @@ -428,12 +360,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v3/rants/#testRantID#/delete" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); From 2b96c1282db186b96249ffa12a94dda0200b56e7 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 16:06:22 +0200 Subject: [PATCH 68/75] v4 certified --- .../api/modules_app/v3/models/BaseService.cfc | 1 + .../api/modules_app/v4/handlers/Echo.cfc | 8 --- .../api/modules_app/v4/handlers/Rants.cfc | 2 +- tests/specs/integration/api-v4/RantsTest.cfc | 72 ------------------- 4 files changed, 2 insertions(+), 81 deletions(-) diff --git a/modules_app/api/modules_app/v3/models/BaseService.cfc b/modules_app/api/modules_app/v3/models/BaseService.cfc index a45c613..9213a37 100644 --- a/modules_app/api/modules_app/v3/models/BaseService.cfc +++ b/modules_app/api/modules_app/v3/models/BaseService.cfc @@ -22,6 +22,7 @@ component accessors="true" { setPrimaryKey( arguments.primaryKey ); setServiceName( arguments.serviceName ); setModuleName( arguments.moduleName ); + return this; } /** diff --git a/modules_app/api/modules_app/v4/handlers/Echo.cfc b/modules_app/api/modules_app/v4/handlers/Echo.cfc index 6d61bed..b2f5ac4 100644 --- a/modules_app/api/modules_app/v4/handlers/Echo.cfc +++ b/modules_app/api/modules_app/v4/handlers/Echo.cfc @@ -3,14 +3,6 @@ */ component extends="coldbox.system.RestHandler" { - // OPTIONAL HANDLER PROPERTIES - this.prehandler_only = ""; - this.prehandler_except = ""; - this.posthandler_only = ""; - this.posthandler_except = ""; - this.aroundHandler_only = ""; - this.aroundHandler_except = ""; - // REST Allowed HTTP Methods Ex: this.allowedMethods = {delete='POST,DELETE',index='GET'} this.allowedMethods = {}; diff --git a/modules_app/api/modules_app/v4/handlers/Rants.cfc b/modules_app/api/modules_app/v4/handlers/Rants.cfc index 8daf35a..3d246e7 100644 --- a/modules_app/api/modules_app/v4/handlers/Rants.cfc +++ b/modules_app/api/modules_app/v4/handlers/Rants.cfc @@ -16,7 +16,7 @@ component extends="coldbox.system.RestHandler" { * Returns a list of Rants */ any function index( event, rc, prc ){ - prc.response.setData( rantService.list().map( ( rant ) => rant.getMemento() ) ); + prc.response.setData( rantService.list().map( rant => rant.getMemento() ) ); } /** diff --git a/tests/specs/integration/api-v4/RantsTest.cfc b/tests/specs/integration/api-v4/RantsTest.cfc index 7de76a3..478e55d 100644 --- a/tests/specs/integration/api-v4/RantsTest.cfc +++ b/tests/specs/integration/api-v4/RantsTest.cfc @@ -14,9 +14,7 @@ component extends="tests.resources.BaseTest" { var event = get( "/api/v4/rants" ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeArray(); expect( returnedJSON.data ).toHaveLengthGTE( 1 ); } ); @@ -31,11 +29,8 @@ component extends="tests.resources.BaseTest" { var rantID = "x" var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -45,11 +40,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = get( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -59,15 +51,11 @@ component extends="tests.resources.BaseTest" { var testRantId = queryExecute( "select id from rants limit 1" ).id; var event = get( "/api/v4/rants/#testRantId#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event ).toHaveStatus( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "rantId" ); expect( returnedJSON.data.rantId ).toBe( testRantId ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLength( 0 ); } ); } ); @@ -90,11 +78,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -103,11 +88,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -116,11 +98,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -129,11 +108,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -142,11 +118,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 400 error", function(){ var event = post( "/api/v4/rants", { "userID" : createUUID(), "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -155,11 +128,8 @@ component extends="tests.resources.BaseTest" { then( "I will get a 404 error", function(){ var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -169,14 +139,10 @@ component extends="tests.resources.BaseTest" { var testUserId = queryExecute( "select id from users limit 1" ).id; var event = post( "/api/v4/rants", { "body" : "xsxswxws", "userID" : testUserId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); expect( returnedJSON.data ).toBeStruct(); expect( returnedJSON.data ).toHaveKey( "rantId" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Created" ); } ); @@ -213,11 +179,8 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", {} ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -227,11 +190,8 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -241,11 +201,8 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -255,11 +212,8 @@ component extends="tests.resources.BaseTest" { var testRant = queryExecute( "select id,userId from rants limit 1" ); var event = put( "/api/v4/rants/#testRant.id#", { "userID" : testRant.userId } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -272,11 +226,8 @@ component extends="tests.resources.BaseTest" { { "userID" : testRant.userId, "body" : "" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -290,11 +241,8 @@ component extends="tests.resources.BaseTest" { { "userID" : testRant.userId, "body" : "abc" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -307,11 +255,8 @@ component extends="tests.resources.BaseTest" { { "body" : "xsxswxws", "userID" : createUUID() } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -324,11 +269,8 @@ component extends="tests.resources.BaseTest" { { "userID" : createUUID(), "body" : "xsxswxws" } ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -342,12 +284,8 @@ component extends="tests.resources.BaseTest" { ); var returnedJSON = event.getRenderData().data; // debug( returnedJSON ); - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Updated" ); } ); @@ -395,11 +333,8 @@ component extends="tests.resources.BaseTest" { var rantID = "abc"; var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 400 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -409,11 +344,8 @@ component extends="tests.resources.BaseTest" { var rantID = createUUID(); var event = delete( "/api/v4/rants/#rantID#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeTrue(); expect( event ).toHaveStatus( 404 ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); } ); } ); @@ -431,12 +363,8 @@ component extends="tests.resources.BaseTest" { var event = delete( "/api/v4/rants/#testRant.getId()#" ); var returnedJSON = event.getRenderData().data; - expect( returnedJSON ).toHaveKey( "error" ); expect( returnedJSON.error ).toBeFalse(); expect( event.getStatusCode() ).toBe( 200 ); - expect( returnedJSON ).toHaveKey( "data" ); - expect( returnedJSON ).toHaveKey( "messages" ); - expect( returnedJSON.messages ).toBeArray(); expect( returnedJSON.messages ).toHaveLengthGTE( 1 ); expect( returnedJSON.messages[ 1 ] ).toBe( "Rant Deleted" ); } ); From 0ec3160c7a5a16db1f7a0b6a501ddb592dd27d59 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 17:38:21 +0200 Subject: [PATCH 69/75] update slug for boxlang --- server-boxlang.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-boxlang.json b/server-boxlang.json index 54e682d..0144ace 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -23,6 +23,6 @@ "BOXLANG_DEBUG":true }, "scripts":{ - "onServerInitialInstall":"install bx-compat,bx-unsafe-evaluate,bx-mysql" + "onServerInitialInstall":"install bx-compat-cfml,bx-unsafe-evaluate,bx-mysql" } } From 375b02ca53e771ed0dc3942c73f765b248b733c7 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 17:39:12 +0200 Subject: [PATCH 70/75] boxlang support --- box.json | 3 +-- server-boxlang.json | 6 +++--- server-lucee.json | 15 --------------- 3 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 server-lucee.json diff --git a/box.json b/box.json index 7b04013..011732e 100644 --- a/box.json +++ b/box.json @@ -51,8 +51,7 @@ }, "scripts":{ "start:adobe":"server start serverConfigFile=server-adobe.json --force", - "start:boxlang":"server start serverConfigFile=server-boxlang.json --force", - "start:lucee":"server start serverConfigFile=server-lucee.json --force", + "start:boxlang":"server start serverConfigFile=server-boxlang.json --force --debug", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", diff --git a/server-boxlang.json b/server-boxlang.json index 0144ace..ea19b92 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -1,5 +1,5 @@ { - "name":"fluentapi-boxlang", + "name":"fluentapi-boxlang", "app":{ "serverHomeDirectory":".engine/boxlang", "cfengine":"boxlang@1" @@ -12,9 +12,9 @@ "enable":"true" } }, - "JVM":{ + "JVM":{ "javaVersion":"openjdk21_jdk", - "args": "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" + "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" }, "cfconfig":{ "file":".cfconfig.json" diff --git a/server-lucee.json b/server-lucee.json deleted file mode 100644 index 324a231..0000000 --- a/server-lucee.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name":"fluentapi-lucee", - "app":{ - "serverHomeDirectory":".engine/lucee5", - "cfengine":"lucee@5" - }, - "web":{ - "http":{ - "port":"60146" - }, - "rewrites":{ - "enable":"true" - } - } -} From 74d32905bbd0e796a2bb322393bbc37cfb66a67f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 17:39:31 +0200 Subject: [PATCH 71/75] use snapshots --- server-boxlang.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-boxlang.json b/server-boxlang.json index ea19b92..041f27b 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -2,7 +2,7 @@ "name":"fluentapi-boxlang", "app":{ "serverHomeDirectory":".engine/boxlang", - "cfengine":"boxlang@1" + "cfengine":"boxlang" }, "web":{ "http":{ From 1dff91b22b7a98b447e5025c03d4691aa64b4378 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 19 Sep 2024 18:42:46 +0200 Subject: [PATCH 72/75] adding be to the demo so we can use boxlang --- box.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/box.json b/box.json index 011732e..caa4746 100644 --- a/box.json +++ b/box.json @@ -28,7 +28,7 @@ "commandbox-migrations":"*" }, "dependencies":{ - "coldbox":"^7", + "coldbox":"be", "cbswagger":"^3", "cbvalidation":"^4", "cors":"^3", From 9365ab0c8c0899e1b02a3b17e50e2258b2724f85 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 20 Sep 2024 11:02:57 +0200 Subject: [PATCH 73/75] be for testing --- server-boxlang.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-boxlang.json b/server-boxlang.json index 041f27b..5385895 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -2,7 +2,7 @@ "name":"fluentapi-boxlang", "app":{ "serverHomeDirectory":".engine/boxlang", - "cfengine":"boxlang" + "cfengine":"boxlang@be" }, "web":{ "http":{ From cc5494c4b5d70cb85e7d238613de3816dfd764c1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 30 Sep 2024 12:25:55 -0700 Subject: [PATCH 74/75] swagger UI --- box.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/box.json b/box.json index caa4746..e5ec8d0 100644 --- a/box.json +++ b/box.json @@ -33,7 +33,8 @@ "cbvalidation":"^4", "cors":"^3", "mementifier":"^3", - "cbdebugger":"^4" + "cbdebugger":"^4", + "cbSwaggerUI":"^1.2.1" }, "installPaths":{ "coldbox":"coldbox/", @@ -44,14 +45,15 @@ "route-visualizer":"modules/route-visualizer/", "cors":"modules/cors/", "mementifier":"modules/mementifier/", - "cbdebugger":"modules/cbdebugger/" + "cbdebugger":"modules/cbdebugger/", + "cbSwaggerUI":"modules/cbSwaggerUI/" }, "testbox":{ "runner":"http://localhost:60146/tests/runner.cfm" }, "scripts":{ "start:adobe":"server start serverConfigFile=server-adobe.json --force", - "start:boxlang":"server start serverConfigFile=server-boxlang.json --force --debug", + "start:boxlang":"server start serverConfigFile=server-boxlang.json --force --debug", "lint":"cflint **.cf* --text --html --json --!exitOnError --suppress", "format":"cfformat run config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc --overwrite --verbose", "format:watch":"cfformat watch config,Application.cfc,modules_app/**/*.cfc,tests/specs/**/*.cfc ./.cfformat.json", From 920c6129fb65cdaace93c967ccde52e90464d7ba Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 30 Sep 2024 12:46:55 -0700 Subject: [PATCH 75/75] change ports --- server-boxlang.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-boxlang.json b/server-boxlang.json index 5385895..6da660e 100644 --- a/server-boxlang.json +++ b/server-boxlang.json @@ -6,7 +6,7 @@ }, "web":{ "http":{ - "port":"60146" + "port":"60147" }, "rewrites":{ "enable":"true" @@ -14,7 +14,7 @@ }, "JVM":{ "javaVersion":"openjdk21_jdk", - "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" + "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8889" }, "cfconfig":{ "file":".cfconfig.json"