You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/09/02 16:27:07 UTC
[03/13] usergrid-javascript git commit: Initial commit of Usergrid
Javascript SDK into its own repo
http://git-wip-us.apache.org/repos/asf/usergrid-javascript/blob/94020d26/tests/test.html
----------------------------------------------------------------------
diff --git a/tests/test.html b/tests/test.html
new file mode 100755
index 0000000..66391d2
--- /dev/null
+++ b/tests/test.html
@@ -0,0 +1,54 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Readme File Tests</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <link rel="stylesheet" href="resources/css/bootstrap-combined.min.css" />
+ <link rel="stylesheet" href="resources/css/styles.css" />
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
+ <script src="../usergrid.js" type="text/javascript"></script>
+ <script src="test.js" type="text/javascript"></script>
+ <script type="text/javascript">
+
+ </script>
+ </head>
+ <body>
+ <div class="header">
+ <img src="resources/images/apigee.png"> App Services (Usergrid) Javascript SDK
+ </div>
+ <div class="info">
+ This sample application runs tests on the sample code examples in the readme file. Tests are run against App Services (Usergrid) using the Usergrid Javascript SDK.
+ </div>
+ <div id="main" class="main">
+ <div class="section-header">README sample code tests</div>
+ <div class="well">
+ <div id="name-control" class="control-group">
+ <div class="controls">
+ <button class="btn btn-primary" id="start-button" style="width: 90px;">Start</button>
+ <span style="clear: both;"> </span>
+ </div>
+ </div>
+ </div>
+ <div class="section-header"><b>Test Output</b></div>
+ <div class="well">
+ <pre id="test-output">// Press Start button to begin</pre>
+ </div>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/usergrid-javascript/blob/94020d26/tests/test.js
----------------------------------------------------------------------
diff --git a/tests/test.js b/tests/test.js
new file mode 100755
index 0000000..f726680
--- /dev/null
+++ b/tests/test.js
@@ -0,0 +1,927 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+* Test suite for all the examples in the readme
+*
+* NOTE: No, this test suite doesn't use the traditional format for
+* a test suite. This is because the goal is to require as little
+* alteration as possible during the copy / paste operation from this test
+* suite to the readme file.
+*
+* @author rod simpson (rod@apigee.com)
+*/
+
+$(document).ready(function () {
+
+//call the runner function to start the process
+$('#start-button').bind('click', function() {
+ $('#start-button').attr("disabled", "disabled");
+ $('#test-output').html('');
+ runner(0);
+});
+
+var logSuccess = true;
+var successCount = 0;
+var logError = true;
+var errorCount = 0;
+var logNotice = true;
+var _username = 'marty2';
+var _email = 'marty2@timetravel.com';
+var _password = 'password2';
+var _newpassword = 'password3';
+
+var client = new Usergrid.Client({
+ orgName:'yourorgname',
+ appName:'sandbox',
+ logging: true, //optional - turn on logging, off by default
+ buildCurl: true //optional - turn on curl commands, off by default
+});
+
+client.logout();
+
+function runner(step, arg, arg2){
+ step++;
+ switch(step)
+ {
+ case 1:
+ notice('-----running step '+step+': DELETE user from DB to prep test');
+ clearUser(step);
+ break;
+ case 2:
+ notice('-----running step '+step+': GET test');
+ testGET(step);
+ break;
+ case 3:
+ notice('-----running step '+step+': POST test');
+ testPOST(step);
+ break;
+ case 4:
+ notice('-----running step '+step+': PUT test');
+ testPUT(step);
+ break;
+ case 5:
+ notice('-----running step '+step+': DELETE test');
+ testDELETE(step);
+ break;
+ case 6:
+ notice('-----running step '+step+': prepare database - remove all dogs (no real dogs harmed here!!)');
+ cleanupAllDogs(step);
+ break;
+ case 7:
+ notice('-----running step '+step+': make a new dog');
+ makeNewDog(step);
+ break;
+ case 8:
+ notice('-----running step '+step+': update our dog');
+ updateDog(step, arg);
+ break;
+ case 9:
+ notice('-----running step '+step+': refresh our dog');
+ refreshDog(step, arg);
+ break;
+ case 10:
+ notice('-----running step '+step+': remove our dog from database (no real dogs harmed here!!)');
+ removeDogFromDatabase(step, arg);
+ break;
+ case 11:
+ notice('-----running step '+step+': make lots of dogs!');
+ makeSampleData(step, arg);
+ break;
+ case 12:
+ notice('-----running step '+step+': make a dogs collection and show each dog');
+ testDogsCollection(step);
+ break;
+ case 13:
+ notice('-----running step '+step+': get the next page of the dogs collection and show each dog');
+ getNextDogsPage(step, arg);
+ break;
+ case 14:
+ notice('-----running step '+step+': get the previous page of the dogs collection and show each dog');
+ getPreviousDogsPage(step, arg);
+ break;
+ case 15:
+ notice('-----running step '+step+': remove all dogs from the database (no real dogs harmed here!!)');
+ cleanupAllDogs(step);
+ break;
+ case 16:
+ notice('-----running step '+step+': prepare database (remove existing user if present)');
+ prepareDatabaseForNewUser(step);
+ break;
+ case 17:
+ notice('-----running step '+step+': create a new user');
+ createUser(step);
+ break;
+ case 18:
+ notice('-----running step '+step+': update the user');
+ updateUser(step, arg);
+ break;
+ case 19:
+ notice('-----running step '+step+': get the existing user');
+ getExistingUser(step, arg);
+ break;
+ case 20:
+ notice('-----running step '+step+': refresh the user from the database');
+ refreshUser(step, arg);
+ break;
+ case 21:
+ notice('-----running step '+step+': log user in');
+ loginUser(step, arg);
+ break;
+ case 22:
+ notice('-----running step '+step+': change users password');
+ changeUsersPassword(step, arg);
+ break;
+ case 23:
+ notice('-----running step '+step+': log user out');
+ logoutUser(step, arg);
+ break;
+ case 24:
+ notice('-----running step '+step+': relogin user');
+ reloginUser(step, arg);
+ break;
+ case 25:
+ notice('-----running step '+step+': logged in user creates dog');
+ createDog(step, arg);
+ break;
+ case 26:
+ notice('-----running step '+step+': logged in user likes dog');
+ userLikesDog(step, arg, arg2);
+ break;
+ case 27:
+ notice('-----running step '+step+': logged in user removes likes connection to dog');
+ removeUserLikesDog(step, arg, arg2);
+ break;
+ case 28:
+ notice('-----running step '+step+': user removes dog');
+ removeDog(step, arg, arg2);
+ break;
+ case 29:
+ notice('-----running step '+step+': log the user out');
+ logoutUser(step, arg);
+ break;
+ case 30:
+ notice('-----running step '+step+': remove the user from the database');
+ destroyUser(step, arg);
+ break;
+ case 31:
+ notice('-----running step '+step+': try to create existing entity');
+ createExistingEntity(step, arg);
+ break;
+ case 32:
+ notice('-----running step '+step+': try to create new entity with no name');
+ createNewEntityNoName(step, arg);
+ break;
+ default:
+ notice('-----test complete!-----');
+ notice('Success count= ' + successCount);
+ notice('Error count= ' + errorCount);
+ notice('-----thank you for playing!-----');
+ $('#start-button').removeAttr("disabled");
+ }
+}
+
+//logging functions
+function success(message){
+ successCount++;
+ if (logSuccess) {
+ console.log('SUCCESS: ' + message);
+ var html = $('#test-output').html();
+ html += ('SUCCESS: ' + message + '\r\n');
+ $('#test-output').html(html);
+ }
+}
+
+function error(message){
+ errorCount++
+ if (logError) {
+ console.log('ERROR: ' + message);
+ var html = $('#test-output').html();
+ html += ('ERROR: ' + message + '\r\n');
+ $('#test-output').html(html);
+ }
+}
+
+function notice(message){
+ if (logNotice) {
+ console.log('NOTICE: ' + message);
+ var html = $('#test-output').html();
+ html += (message + '\r\n');
+ $('#test-output').html(html);
+ }
+}
+
+//tests
+function clearUser(step) {
+ var options = {
+ method:'DELETE',
+ endpoint:'users/fred'
+ };
+ client.request(options, function (err, data) {
+ //data will contain raw results from API call
+ success('User cleared from DB');
+ runner(step);
+ });
+}
+
+function testGET(step) {
+ var options = {
+ method:'GET',
+ endpoint:'users'
+ };
+ client.request(options, function (err, data) {
+ if (err) {
+ error('GET failed');
+ } else {
+ //data will contain raw results from API call
+ success('GET worked');
+ runner(step);
+ }
+ });
+}
+
+function testPOST(step) {
+ var options = {
+ method:'POST',
+ endpoint:'users',
+ body:{ username:'fred', password:'secret' }
+ };
+ client.request(options, function (err, data) {
+ if (err) {
+ error('POST failed');
+ } else {
+ //data will contain raw results from API call
+ success('POST worked');
+ runner(step);
+ }
+ });
+}
+
+function testPUT(step) {
+ var options = {
+ method:'PUT',
+ endpoint:'users/fred',
+ body:{ newkey:'newvalue' }
+ };
+ client.request(options, function (err, data) {
+ if (err) {
+ error('PUT failed');
+ } else {
+ //data will contain raw results from API call
+ success('PUT worked');
+ runner(step);
+ }
+ });
+}
+
+function testDELETE(step) {
+ var options = {
+ method:'DELETE',
+ endpoint:'users/fred'
+ };
+ client.request(options, function (err, data) {
+ if (err) {
+ error('DELETE failed');
+ } else {
+ //data will contain raw results from API call
+ success('DELETE worked');
+ runner(step);
+ }
+ });
+}
+
+function makeNewDog(step) {
+
+ var options = {
+ type:'dogs',
+ name:'Rocky'
+ }
+
+ client.createEntity(options, function (err, dog) {
+ if (err) {
+ error('dog not created');
+ } else {
+ success('dog is created');
+
+ //once the dog is created, you can set single properties:
+ dog.set('breed','Dinosaur');
+
+ //the set function can also take a JSON object:
+ var data = {
+ master:'Fred',
+ state:'hungry'
+ }
+ //set is additive, so previously set properties are not overwritten
+ dog.set(data);
+
+ //finally, call save on the object to save it back to the database
+ dog.save(function(err){
+ if (err){
+ error('dog not saved');
+ } else {
+ success('new dog is saved');
+ runner(step, dog);
+ }
+ });
+ }
+ });
+
+}
+
+function updateDog(step, dog) {
+
+ //change a property in the object
+ dog.set("state", "fed");
+ //and save back to the database
+ dog.save(function(err){
+ if (err){
+ error('dog not saved');
+ } else {
+ success('dog is saved');
+ runner(step, dog);
+ }
+ });
+
+}
+
+function refreshDog(step, dog){
+
+ //call fetch to refresh the data from the server
+ dog.fetch(function(err){
+ if (err){
+ error('dog not refreshed from database');
+ } else {
+ //dog has been refreshed from the database
+ //will only work if the UUID for the entity is in the dog object
+ success('dog entity refreshed from database');
+ runner(step, dog);
+ }
+ });
+
+}
+
+function removeDogFromDatabase(step, dog){
+
+ //the destroy method will delete the entity from the database
+ dog.destroy(function(err){
+ if (err){
+ error('dog not removed from database');
+ } else {
+ success('dog removed from database'); // no real dogs were harmed!
+ dog = null; //no real dogs were harmed!
+ runner(step, 1);
+ }
+ });
+
+}
+
+function makeSampleData(step, i) {
+ notice('making dog '+i);
+
+ var options = {
+ type:'dogs',
+ name:'dog'+i,
+ index:i
+ }
+
+ client.createEntity(options, function (err, dog) {
+ if (err) {
+ error('dog ' + i + ' not created');
+ } else {
+ if (i >= 30) {
+ //data made, ready to go
+ success('all dogs made');
+ runner(step);
+ } else {
+ success('dog ' + i + ' made');
+ //keep making dogs
+ makeSampleData(step, ++i);
+ }
+ }
+ });
+}
+
+function testDogsCollection(step) {
+
+ var options = {
+ type:'dogs',
+ qs:{ql:'order by index'}
+ }
+
+ client.createCollection(options, function (err, dogs) {
+ if (err) {
+ error('could not make collection');
+ } else {
+
+ success('new Collection created');
+
+ //we got the dogs, now display the Entities:
+ while(dogs.hasNextEntity()) {
+ //get a reference to the dog
+ dog = dogs.getNextEntity();
+ var name = dog.get('name');
+ notice('dog is called ' + name);
+ }
+
+ success('looped through dogs');
+
+ //create a new dog and add it to the collection
+ var options = {
+ name:'extra-dog',
+ fur:'shedding'
+ }
+ //just pass the options to the addEntity method
+ //to the collection and it is saved automatically
+ dogs.addEntity(options, function(err, dog, data) {
+ if (err) {
+ error('extra dog not saved or added to collection');
+ } else {
+ success('extra dog saved and added to collection');
+ runner(step, dogs);
+ }
+ });
+ }
+ });
+
+}
+
+function getNextDogsPage(step, dogs) {
+
+ if (dogs.hasNextPage()) {
+ //there is a next page, so get it from the server
+ dogs.getNextPage(function(err){
+ if (err) {
+ error('could not get next page of dogs');
+ } else {
+ success('got next page of dogs');
+ //we got the next page of data, so do something with it:
+ var i = 11;
+ while(dogs.hasNextEntity()) {
+ //get a reference to the dog
+ var dog = dogs.getNextEntity();
+ var index = dog.get('index');
+ if(i !== index) {
+ error('wrong dog loaded: wanted' + i + ', got ' + index);
+ }
+ notice('got dog ' + i);
+ i++
+ }
+ success('looped through dogs')
+ runner(step, dogs);
+ }
+ });
+ } else {
+ getPreviousDogsPage(dogs);
+ }
+
+}
+
+function getPreviousDogsPage(step, dogs) {
+
+ if (dogs.hasPreviousPage()) {
+ //there is a previous page, so get it from the server
+ dogs.getPreviousPage(function(err){
+ if(err) {
+ error('could not get previous page of dogs');
+ } else {
+ success('got next page of dogs');
+ //we got the previous page of data, so do something with it:
+ var i = 1;
+ while(dogs.hasNextEntity()) {
+ //get a reference to the dog
+ var dog = dogs.getNextEntity();
+ var index = dog.get('index');
+ if(i !== index) {
+ error('wrong dog loaded: wanted' + i + ', got ' + index);
+ }
+ notice('got dog ' + i);
+ i++
+ }
+ success('looped through dogs');
+ runner(step);
+ }
+ });
+ } else {
+ getAllDogs();
+ }
+}
+
+function cleanupAllDogs(step){
+
+ var options = {
+ type:'dogs',
+ qs:{limit:50} //limit statement set to 50
+ }
+
+ client.createCollection(options, function (err, dogs) {
+ if (err) {
+ error('could not get all dogs');
+ } else {
+ success('got at most 50 dogs');
+ //we got 50 dogs, now display the Entities:
+ while(dogs.hasNextEntity()) {
+ //get a reference to the dog
+ var dog = dogs.getNextEntity();
+ var name = dog.get('name');
+ notice('dog is called ' + name);
+ }
+ dogs.resetEntityPointer();
+ //do doggy cleanup
+ while(dogs.hasNextEntity()) {
+ //get a reference to the dog
+ var dog = dogs.getNextEntity();
+ var dogname = dog.get('name');
+ notice('removing dog ' + dogname + ' from database');
+ dog.destroy(function(err, data) {
+ if (err) {
+ error('dog not removed');
+ } else {
+ success('dog removed');
+ }
+ });
+ }
+
+ //no need to wait around for dogs to be removed, so go on to next test
+ runner(step);
+ }
+ });
+}
+
+
+function prepareDatabaseForNewUser(step) {
+ var options = {
+ method:'DELETE',
+ endpoint:'users/'+_username
+ };
+ client.request(options, function (err, data) {
+ if (err) {
+ notice('database ready - no user to delete');
+ runner(step);
+ } else {
+ //data will contain raw results from API call
+ success('database ready - user deleted worked');
+ runner(step);
+ }
+ });
+}
+
+
+function createUser(step) {
+ client.signup(_username, _password, _email, 'Marty McFly',
+ function (err, marty) {
+ if (err){
+ error('user not created');
+ runner(step, marty);
+ } else {
+ success('user created');
+ runner(step, marty);
+ }
+ }
+ );
+}
+
+function updateUser(step, marty) {
+
+ //add properties cumulatively
+ marty.set('state', 'California');
+ marty.set("girlfriend","Jennifer");
+ marty.save(function(err){
+ if (err){
+ error('user not updated');
+ } else {
+ success('user updated');
+ runner(step, marty);
+ }
+ });
+
+}
+
+function getExistingUser(step, marty) {
+
+ var options = {
+ type:'users',
+ username:_username
+ }
+ client.getEntity(options, function(err, existingUser){
+ if (err){
+ error('existing user not retrieved');
+ } else {
+ success('existing user was retrieved');
+
+ var username = existingUser.get('username');
+ if (username === _username){
+ success('got existing user username');
+ } else {
+ error('could not get existing user username');
+ }
+ runner(step, marty);
+ }
+ });
+
+}
+
+
+function refreshUser(step, marty) {
+
+ marty.fetch(function(err){
+ if (err){
+ error('not refreshed');
+ } else {
+ success('user refreshed');
+ runner(step, marty);
+ }
+ });
+
+}
+
+function loginUser(step, marty) {
+ username = _username;
+ password = _password;
+ client.login(username, password,
+ function (err) {
+ if (err) {
+ error('could not log user in');
+ } else {
+ success('user has been logged in');
+
+ //the login call will return an OAuth token, which is saved
+ //in the client. Any calls made now will use the token.
+ //once a user has logged in, their user object is stored
+ //in the client and you can access it this way:
+ var token = client.token;
+
+ //Then make calls against the API. For example, you can
+ //get the user entity this way:
+ client.getLoggedInUser(function(err, data, user) {
+ if(err) {
+ error('could not get logged in user');
+ } else {
+ success('got logged in user');
+
+ //you can then get info from the user entity object:
+ var username = user.get('username');
+ notice('logged in user was: ' + username);
+
+ runner(step, user);
+ }
+ });
+
+ }
+ }
+ );
+}
+
+function changeUsersPassword(step, marty) {
+
+ marty.set('oldpassword', _password);
+ marty.set('newpassword', _newpassword);
+ marty.save(function(err){
+ if (err){
+ error('user password not updated');
+ } else {
+ success('user password updated');
+ runner(step, marty);
+ }
+ });
+
+}
+
+function logoutUser(step, marty) {
+
+ //to log the user out, call the logout() method
+ client.logout();
+
+ //verify the logout worked
+ if (client.isLoggedIn()) {
+ error('logout failed');
+ } else {
+ success('user has been logged out');
+ }
+
+ runner(step, marty);
+}
+
+function reloginUser(step, marty) {
+
+ username = _username
+ password = _newpassword;
+ client.login(username, password,
+ function (err) {
+ if (err) {
+ error('could not relog user in');
+ } else {
+ success('user has been re-logged in');
+ runner(step, marty);
+ }
+ }
+ );
+}
+
+
+
+//TODO: currently, this code assumes permissions have been set to support user actions. need to add code to show how to add new role and permission programatically
+//
+//first create a new permission on the default role:
+//POST "https://api.usergrid.com/yourorgname/yourappname/roles/default/permissions" -d '{"permission":"get,post,put,delete:/dogs/**"}'
+//then after user actions, delete the permission on the default role:
+//DELETE "https://api.usergrid.com/yourorgname/yourappname/roles/default/permissions?permission=get%2Cpost%2Cput%2Cdelete%3A%2Fdogs%2F**"
+
+
+function createDog(step, marty) {
+
+ var options = {
+ type:'dogs',
+ name:'einstein',
+ breed:'mutt'
+ }
+
+ client.createEntity(options, function (err, dog) {
+ if (err) {
+ error('POST new dog by logged in user failed');
+ } else {
+ success('POST new dog by logged in user succeeded');
+ runner(step, marty, dog);
+ }
+ });
+
+}
+
+function userLikesDog(step, marty, dog) {
+
+ marty.connect('likes', dog, function (err, data) {
+ if (err) {
+ error('connection not created');
+ runner(step, marty);
+ } else {
+
+ //call succeeded, so pull the connections back down
+ marty.getConnections('likes', function (err, data) {
+ if (err) {
+ error('could not get connections');
+ } else {
+ //verify that connection exists
+ if (marty.likes.einstein) {
+ success('connection exists');
+ } else {
+ error('connection does not exist');
+ }
+
+ runner(step, marty, dog);
+ }
+ });
+ }
+ });
+
+}
+
+function removeUserLikesDog(step, marty, dog) {
+
+ marty.disconnect('likes', dog, function (err, data) {
+ if (err) {
+ error('connection not deleted');
+ runner(step, marty);
+ } else {
+
+ //call succeeded, so pull the connections back down
+ marty.getConnections('likes', function (err, data) {
+ if (err) {
+ error('error getting connections');
+ } else {
+ //verify that connection exists
+ if (marty.likes.einstein) {
+ error('connection still exists');
+ } else {
+ success('connection deleted');
+ }
+
+ runner(step, marty, dog);
+ }
+ });
+ }
+ });
+
+}
+
+function removeDog(step, marty, dog) {
+
+ //now delete the dog from the database
+ dog.destroy(function(err, data) {
+ if (err) {
+ error('dog not removed');
+ } else {
+ success('dog removed');
+ }
+ });
+ runner(step, marty);
+}
+
+function destroyUser(step, marty) {
+
+ marty.destroy(function(err){
+ if (err){
+ error('user not deleted from database');
+ } else {
+ success('user deleted from database');
+ marty = null; //blow away the local object
+ runner(step);
+ }
+ });
+
+}
+
+function createExistingEntity(step, marty) {
+
+ var options = {
+ type:'dogs',
+ name:'einstein'
+ }
+
+ client.createEntity(options, function (err, dog) {
+ if (err) {
+ error('Create new entity to use for existing entity failed');
+ } else {
+ success('Create new entity to use for existing entity succeeded');
+
+ var uuid = dog.get('uuid');
+ //now create new entity, but use same entity name of einstein. This means that
+ //the original einstein entity now exists. Thus, the new einstein entity should
+ //be the same as the original + any data differences from the options var:
+
+ options = {
+ type:'dogs',
+ name:'einstein',
+ breed:'mutt'
+ }
+ client.createEntity(options, function (err, newdog) {
+ if (err) {
+ error('Create new entity to use for existing entity failed');
+ } else {
+ success('Create new entity to use for existing entity succeeded');
+
+ var newuuid = newdog.get('uuid');
+ if (newuuid === uuid) {
+ success('UUIDs of new and old entities match');
+ } else {
+ error('UUIDs of new and old entities do not match');
+ }
+
+ var breed = newdog.get('breed');
+ if (breed === 'mutt') {
+ success('attribute sucesfully set on new entity');
+ } else {
+ error('attribute not sucesfully set on new entity');
+ }
+
+ newdog.destroy(function(err){
+ if (err){
+ error('existing entity not deleted from database');
+ } else {
+ success('existing entity deleted from database');
+ dog = null; //blow away the local object
+ newdog = null; //blow away the local object
+ runner(step);
+ }
+ });
+
+ }
+ });
+ }
+ });
+
+}
+
+function createNewEntityNoName(step, marty) {
+
+ var options = {
+ type:"something",
+ othervalue:"something else"
+ }
+
+ client.createEntity(options, function (err, entity) {
+ if (err) {
+ error('Create new entity with no name failed');
+ } else {
+ success('Create new entity with no name succeeded');
+
+ entity.destroy();
+ runner(step);
+ }
+ });
+
+}
+
+});
\ No newline at end of file