Skip to content

Instantly share code, notes, and snippets.

@selahlynch
Created August 21, 2014 21:18
Show Gist options
  • Save selahlynch/05eee582890fc455a33b to your computer and use it in GitHub Desktop.
Save selahlynch/05eee582890fc455a33b to your computer and use it in GitHub Desktop.
MacroSim - code for presentation
'use strict';
//make assumption that players S1-S6 exist
describe('Macrosim Homepage', function() {
beforeEach(function(){
//login to macrosim
browser.get('http://localhost:4444/simulate/lldev/macrosim/simulation/#/login');
element(by.id('user_name')).sendKeys("fac_macrosim");
element(by.id('password')).sendKeys("wharton");
element(by.id('sign-in-button')).click();
browser.get('http://localhost:4444/simulate/lldev/macrosim/');
});
it('should place and retrieve data successfully', function() {
var GroupData;
browser.executeAsyncScript(function(callback) {
GroupData = angular.element('body').injector().get('GroupData');
GroupData.put('someTestLocation', "someTestData").then(callback);
});
expect(browser.executeAsyncScript(function(callback) {
GroupData.get('someTestLocation').then(callback);
})).toEqual("someTestData");
});
});
//TODO - think about cleaning things up and leaving them in a state similar to what it had been
'use strict';
describe('data-service tests', function () {
var $q, $rootScope, $httpBackend, GroupData;
beforeEach(function () {
module('simulateApp');
inject(function (_$q_, _$rootScope_, _$httpBackend_, _GroupData_) {
$q = _$q_;
$rootScope = _$rootScope_;
$httpBackend = _$httpBackend_;
GroupData = _GroupData_;
});
});
var SIMNAME = "lldev/macrosim";
it('should get data from the appropriate URL when passed a string key', function () {
var retVal;
$httpBackend.expectGET('/simulate/api/data/' + SIMNAME + '/bob?scope=GROUP').respond({"status_code":"200","data":{"bob":"3"}});
GroupData.get("bob").then(function(r){retVal = r});
$httpBackend.flush();
expect(retVal).toEqual("3");
});
it('should get data from the appropriate URL when passed an array key', function () {
var retVal;
$httpBackend.expectGET('/simulate/api/data/' + SIMNAME + '/bob/stan?scope=GROUP').respond({"status_code":"200","data":{"stan":"3"}});
GroupData.get(["bob","stan"]).then(function(r){retVal = r});
$httpBackend.flush();
expect(retVal).toEqual("3");
});
it('should put data to the appropriate URL', function () {
var retVal;
$httpBackend.expectPOST('/simulate/api/data/' + SIMNAME + '/bob', "value=3&data_action=SET&scope=GROUP").respond({ message: "Action executed successfully.", status_code: "201" });
GroupData.put("bob", 3).then(function(r){retVal = r});
$httpBackend.flush();
expect(retVal).toEqual({});
});
it('should push data to the appropriate URL', function () {
var retVal;
$httpBackend.expectPOST('/simulate/api/data/' + SIMNAME + '/bob', "value=3&data_action=PUSH&scope=GROUP").respond({ message: "Action executed successfully.", status_code: "201" });
GroupData.post("bob", 3).then(function(r){retVal = r});
$httpBackend.flush();
expect(retVal).toEqual({});
});
it('should delete data from the appropriate URL', function () {
var retVal;
$httpBackend.expectDELETE('/simulate/api/data/' + SIMNAME + '/bob?scope=GROUP').respond({ message: "Data deleted.", status_code: "201" });
GroupData.delete("bob").then(function(r){retVal = r});
$httpBackend.flush();
expect(retVal).toEqual({});
});
});
//This is a service to give convenient access to the DataAPI.
//All data is considered to be in group scope.
//Examples:
//GroupData.get("roleAssignments");
//GroupData.get(["roleAssignments", "User1"]);
//GroupData.put(["roleAssignments", "User1"], {team:"1", role:"Mon"});
//GroupData.delete(["roleAssignments", "User1"]);
//TODO - test how this handle arrays in the DataAPI, best to pass index as string or as number
angular.module('simulateApp').
factory('GroupData', ['SimulateEndpoint', function (SimulateEndpoint) {
var DataApi = SimulateEndpoint({
name: 'data'
});
//if input it a string, it returns an array with one entry which is that string
var forceArray = function(stringOrStrings){
var strings;
if(! (stringOrStrings instanceof Array)){
strings = [stringOrStrings];
}
else{
strings = stringOrStrings;
}
return strings;
};
//converts an array to a hash that can be understood by the SimulateEndpoint service
var convertUrlParams = function(urlArray){
var urlObj = {};
urlArray = forceArray(urlArray);
_.each(urlArray, function(item, cnt){
var key = "_url"+cnt;
urlObj[key] = item;
});
return urlObj;
};
//get data from the defined location
//param 'keys' - a string or an array of strings defining a data location
// behind the scenes it is defining the URL path of the Data API call
var get = function (keys) {
keys = forceArray(keys);
var params = convertUrlParams(keys);
params.scope = "GROUP"
var lastkey = keys[keys.length-1];
return DataApi.get(params).then(function(res){
return res.data[lastkey];
});
};
//TODO - right now all bool values get converted to strings, figure out how to fix this, or document this
//place or replace data at the defined location
var put = function (keys, data) {
var params = {
value: _.isString(data) ? data : JSON.stringify(data), // need to make this a string to comply with Forio API
data_action: "SET",
scope: "GROUP"
};
angular.extend(params, convertUrlParams(keys));
return DataApi.post(params).then(function(){return {};});
};
//push value to end of an array at the defined location
var post = function (keys, data) {
var params = {
value: _.isString(data) ? data : JSON.stringify(data), // need to make this a string to comply with Forio API
data_action: "PUSH",
scope: "GROUP"
};
angular.extend(params, convertUrlParams(keys));
return DataApi.post(params).then(function(){return {};});
};
return {
put: put,
get: get,
post:post,
//delete data from the defined location
delete:function(keys){
var params = convertUrlParams(keys);
params.scope = "GROUP";
return DataApi.delete(params).then(function(){return {};});
}
};
}]);
'use strict';
//make assumption that players S1-S6 exist
describe('Macrosim Homepage', function() {
beforeEach(function(){
//login to macrosim
browser.get('http://localhost:4444/simulate/lldev/macrosim/simulation/#/login');
element(by.id('user_name')).sendKeys("fac_macrosim");
element(by.id('password')).sendKeys("wharton");
element(by.id('sign-in-button')).click();
browser.get('http://localhost:4444/simulate/lldev/macrosim/#/instructorManagePlayers');
});
it('should navigate successfully to Manage Players', function() {
expect(element(by.css('.navbar-brand')).getText()).toEqual('Manage Players');
});
it('should unassign all and auto assign all successfully', function(){
element(by.css('.row.ng-scope')).evaluate('changeUserTeamRole({loginId:"s1"}, "1", "Monetary", true)');
element(by.id('unassign-all')).click();
expect(element(by.css('.row.ng-scope')).evaluate('atLeastOnePlayerAssigned')).toEqual(false);
element(by.id('auto-assign')).click();
expect(element(by.css('.row.ng-scope')).evaluate('atLeastOnePlayerAssigned')).toEqual(true);
});
});
//inactivate a player
//activate a player
//assign all while one play is inactivated
//assign a player to a team
describe('mocking services', function () {
var deferred, deferred_GroupData_get, deferred_UserGroup_getUsers, rootScope, UsersAndRoles, ExampleMock;
beforeEach(function () {
module('simulateApp');
module(function($provide){
$provide.factory('ExampleMock', function($q){
return{
trySynch: function(){
return 33;
},
tryAsynch: function(){
deferred = $q.defer();
return deferred.promise;
}
};
});
$provide.factory('GroupData', function($q){
return{
get: function(){
deferred_GroupData_get = $q.defer();
return deferred_GroupData_get.promise;
}
};
});
$provide.factory('UserGroup', function($q){
return{
getUsers: function(){
deferred_UserGroup_getUsers = $q.defer();
return deferred_UserGroup_getUsers.promise;
}
};
});
});
inject(function ($injector) {
ExampleMock = $injector.get('ExampleMock');
//TODO - remove UserGroup and GroupData, i think this step is unnecessary
// UserGroup = $injector.get('UserGroup');
// GroupData = $injector.get('GroupData');
rootScope = $injector.get('$rootScope');
UsersAndRoles = $injector.get('UsersAndRoles');
});
});
it('should be able to get a list of users', function () {
var retVal;
UsersAndRoles.getUsers().then(function(r){
retVal = r;
});
//TODO - put more data here
deferred_UserGroup_getUsers.resolve(apiStubs.UserGroup.getUsers);
deferred_GroupData_get.resolve(apiStubs.GroupData.get.RoleAssignments);
rootScope.$digest();
expect(retVal).toEqual(apiStubs.UsersAndRoles.getUsers);
});
it('should be able to test values from both functions', function () {
expect(ExampleMock.trySynch()).toEqual(33);
var retVal;
ExampleMock.tryAsynch().then(function(r){
retVal = r;
});
deferred.resolve(44);
rootScope.$digest();
expect(retVal).toEqual(44);
});
});
//This service combines user from the UserGroup API and the RoleAssignments from the Data API and presents it as one entity
//This combined entity will be presented in the same format that would come from UserGroup API if all the role assignments were held in the UserGroupAPI
// example format of RoleAssignments in Data API
// {
// 's1' : {team:"1", role:"Fiscal"},
// 's3' : {team:"1", role:"Monetary"},
// 's4' : {team:"2", role:"Fiscal"},
// }
// NOTE, any time a user is unassigned its entry will be DELETED from roleAssignments, it will not be saved as {team:"", role:""}
//
angular.module('simulateApp').
factory('UsersAndRoles', ['$q', 'UserGroup', 'GroupData', 'User', function ($q, UserGroup, GroupData, User) {
var roleAssignmentdataAPIKey = "RoleAssignments"; //this is assumed to be a string and not an array
var assignUser = function(userId, team, role){
return GroupData.put([roleAssignmentdataAPIKey, userId], {team:team, role:role});
};
var unAssignUser = function(userId){
return GroupData.delete([roleAssignmentdataAPIKey, userId]);
};
var inactivateUser = function(userId){
return User.update(userId, {active:false});
};
var activateUser = function(userId){
return User.update(userId, {active:true});
};
//queries UserGroup API and role assignments from Data API
//
var getUsers = function () {
return $q.all([UserGroup.getUsers(), GroupData.get(roleAssignmentdataAPIKey)]).then(function(results){
var users = results[0];
var roleAssignments = results[1];
if(!roleAssignments){
roleAssignments = {};
}
users = _.map(users, function(u){
var roleAssignment = roleAssignments[u.loginId];
if(roleAssignment){
u.team = roleAssignment.team;
u.role = roleAssignment.role;
}
else{
u.team = "";
u.role = "";
}
return u;
});
return users;
});
};
return {
//makes assumption that all roles are in the DataAPI
//moves roles to UserGroupAPI and removes any role information from Data API
applyRolesToUserAPI: function(){
return UserGroup.unAssignAll().then(function(r){
return GroupData.get(roleAssignmentdataAPIKey).then(function(roleAssignments){
var userUpdatePromises = _.map(roleAssignments, function(assignment, loginId){
return User.update(loginId, {role: assignment.role, team: assignment.team});
});
return $q.all(userUpdatePromises).then(function(){
return GroupData.delete(roleAssignmentdataAPIKey);
});
});
});
},
//gets all User and Role information combines data from UserGroup and Data API
//to return a set of users that looks as if it one was managing users with the User API
//and the data had been taken direct from the UserGroup API
getUsers: getUsers,
getStudentUsers : function(){
return getUsers().then(function(users){
var studentUsers = _.filter(users, function(user){
return (!user.isFacilitator);
});
return studentUsers;
});
},
//this take the desired team, role and active status for a user and makes it so
//it touches both the GroupData API and the User API
changeUserTeamRole: function (userID, team, role, isActive) {
var processActivation = function(){
if(isActive){
return activateUser(userID);
}
else{
return inactivateUser(userID);
}
};
var processAssignment = function(){
if(team===""&&role===""){
return unAssignUser(userID);
}
else{
return assignUser(userID, team, role)
}
};
return processActivation().then(processAssignment);
},
//note this assigns the players from scratch
//role param - assumed to only include the tournament roles
assignAll: function (numTeams, roles) {
return UserGroup.getUsers().then(function(results){
var users = results;
var activeStudentUsers = _.filter(users, function(user){
return ((!user.isFacilitator) && user.active );
});
var numRoles = roles.length;
var roleAssignments = {};
_.each(activeStudentUsers, function(user, cnt){
roleAssignments[user.loginId] = {
role: roles[cnt % numRoles],
team: Math.floor(cnt/numRoles) % numTeams + 1
};
});
return GroupData.put(roleAssignmentdataAPIKey, roleAssignments);
});
},
unAssignAll: function () {
return GroupData.put(roleAssignmentdataAPIKey, {});
}
};
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment