<commit_before>// when document loads
$(document).ready(function () {

  // construct local favorites list
  $.get('/api/user/favorites', function(courses) {
    document.favorites = []
    for (var course in courses) {
      document.favorites.push(courses[course]["_id"])
    }
  })

  // get User
  var thisUser = this.User
  $.get('/api/whoami', function (data) {
    $('#nav-netid').html('')
    $('#nav-netid').append(data['netid'])
  })

  // initial displaying favorites
  var dispFavorites = function() {

    // call api to get favorites and display
    $.get('/api/user/favorites', function(courses) {

      $('#favorite-title').css('display', (courses == undefined || courses.length == 0) ? 'none' : 'block')

      $('#favs').html('');
      $('#favorite-title').html('');

      $('#favorite-title').append(courses.length + ' Favorite Course' + (courses.length !== 1 ? 's' : ''))
      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex];

        // append favorite into favs pane
        $('#favs').append(newDOMResult(thisCourse));
      }
    })
  }

  // function for updating search results
  var getCourseData = function () {
    var query = {
      $text: {
        $search: $('#searchbox').val()
      },
      semester: $('#semester').val()
    }

    $.post('/api/courses',
    {
      query: JSON.stringify(query),
      sort: $('#sort').val()
    }, function (courses, status) {
      // Basic error handling
      if (status !== 'success') {
        window.alert('An error occured and your search could not be completed.')
      }

      // clear results
      $('#results').html('')
      $('#search-title').html('')

      $('#search-title').append(courses.length + ' Search Result' + (courses.length !== 1 ? 's' : ''))

      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex]
        $('#results').append(newDOMResult(thisCourse))
      }
    })
  }

  // function for displaying course details
  var dispCourseData = function() {
    $(".search-result").removeClass("active");
    $("#welcome-display-pane").css("display", "none");
    $("#display-pane").css("display", "");
    //document.getElementById("display-pane").style.display = "inline";
    $(this).addClass("active")

    $('#disp-title').html('')
    $('#disp-subtitle').html('')
    $('#disp-profs').html('')
    $('#disp-body').html('')
    $('#evals').html('')
    $('#comments').html('')

    var thisCourse = this.course

    // string for course listings
    var listings =  getListings(thisCourse)

    $('#disp-title').append(thisCourse.title)

    $('#disp-subtitle').append(listings + ' '
                            + (thisCourse.distribution == undefined ? '' : ' ' + thisCourse.distribution + '')
                            + (thisCourse.pdf["required"]  ? ' PDF ONLY'
                            : (thisCourse.pdf["permitted"] ? ' PDF'
                                                                   : ' NPDF'))
                            + (thisCourse.audit ? ' AUDIT' : '')
                            /*+ ' Favorite'*/
                            + (thisCourse.website == undefined ? '' : ' '))

    //$('#fav-button')[0].course = thisCourse;
    //$('#comments').append(thisCourse.evaluations.studentComments)
    // stuff for course evaluations
    var evals = ""
    for (var field in thisCourse.evaluations.scores) {
      var val = thisCourse.evaluations.scores[field]
      evals += '
' + field + '
'
             + '

'
             + val.toFixed(2) + '

' // as percentage of 5
    }
    if (evals == "") {
      $('#evals').append('No course evaluations available.')
    }
    else {
      $('#evals').append(evals)
    }

    // stuff for student comments
    var comments = ""
    for (var studentComment in thisCourse.evaluations.studentComments) {
        var val = thisCourse.evaluations.studentComments[studentComment]
        comments += '
' + val + '
'
    }
    if (comments == "") {
      $('#comments').append('No student comments available.')
    }
    else {
      $('#comments').append(comments)
    }

    var dispbody = ''
    dispbody += '

'
                + '

'
                + '
' + thisCourse.description + '
'
                + (thisCourse.prerequisites == undefined ? '' :
                '
Prerequisites

' + thisCourse.prerequisites + '
')
                + (thisCourse.equivalentcourses == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.equivalentcourses + '
')
                + (thisCourse.otherinformation == undefined ? '' :
                '
Other Information

' + thisCourse.otherinformation + '
')
                + (thisCourse.otherrequirements == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.otherrequirements + '
')
                // '
Classes

' + thisCourse.classes[0] + '
'

    var openClasses = { table: '' };
    var closedClasses = { table: '' };
    var cancelledClasses = { table: '' };

    // Show classes of a course
    var makeClassTable = function(val, classes) {
      classes.table += '
'
                + '' + val['section'] + '	'
                + ''
        for (var day in val.schedule.meetings[0].days) {
          //classes += thisCourse.classes.schedule.meetings[0].days[day]
          classes.table += val.schedule.meetings[0].days[day] + ' '
        }
        classes.table += '	'
        classes.table += (val.schedule.meetings[0] == undefined ? '' :
                  '' + (val.schedule.meetings[0].start_time == undefined ? '' :
                    val.schedule.meetings[0].start_time) + ' - '
                  + (val.schedule.meetings[0].end_time == undefined ? '' :
                    val.schedule.meetings[0].end_time) + '	'
                  + '' + (val.schedule.meetings[0].building == undefined ? '' :
                    val.schedule.meetings[0].building.short_name) + ' '
                  + (val.schedule.meetings[0].room == undefined ? '' :
                    val.schedule.meetings[0].room) + '	'
                )
        classes.table += '' + val['enrollment'] + ' / ' + val['capacity'] + '	'
                  + '
'
    }

    for (var field in thisCourse.classes) {
      var val = thisCourse.classes[field]
      if (val['status'] == "Open") {
        makeClassTable(val, openClasses);
      }
      if (val['status'] == "Cancelled") {
        makeClassTable(val, cancelledClasses);
      }
      if (val['status'] == "Closed") {
        makeClassTable(val, closedClasses);
      }
    }
    dispbody += (openClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Open Classes
' + openClasses.table + '
');
    dispbody += (closedClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Closed Classes
' + closedClasses.table + '
');
    dispbody += (cancelledClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Cancelled Classes
' + cancelledClasses.table + '
');
    $('#disp-body').append(dispbody)

    for (var instructor in thisCourse.instructors) {
      var name = ''
               + thisCourse.instructors[instructor].name['first'] + ' '
               + thisCourse.instructors[instructor].name['last'] + ''
        if ($('#disp-profs').html() !== '') {
          $('#disp-profs').append(', ')
        }
        $('#disp-profs').append(name)
    }

    // favorite a course
    $("#fav-button").click(function() {
      var thisCourseId = this.course["_id"];
      if (thisUser.favoriteCourses.includes(thisCourseId))
      {
        $.ajax({
          url: '/api/user/favorite',
          type: 'PUT',
          data: {'course': thisCourseId},
          success: function() {dispFavorites();}
        });
      }
      else {
        $.ajax({
          url: '/api/user/favorite',
          type: 'DELETE',
          data: {'course': thisCourseId},
          success: function() {dispFavorites();}
        });
      }
    })

    var prevInstId = 0;
    $('.course-prof').on("click",function(){
      var instId =  $(this).attr("id");
      if (instId != prevInstId)
      {
        $('#instructor-info').hide();
        toggleInstructor(instId);
      }
      else
      {
        $('#instructor-info').slideToggle();
      }
      prevInstId = instId;
    })

    // Instructor page toggling
    var toggleInstructor = function(instId) {
      $('#instructor-info').html('');
      var instInfo = '';

      $.get('/api/instructor/' + instId, function (data) {
        var thisInst = data;
        instInfo += '
 Courses taught by ' + thisInst.name['first'] + ' ' + thisInst.name['last'] + '
';
        instInfo += '
'
        $('#instructor-info').append(instInfo);
        for (var courseIndex in thisInst.courses) {
          var thisCourse = thisInst.courses[courseIndex];
          var entry = $.parseHTML(newInstructorCourseEntry(thisCourse))[0];
          entry.course = thisCourse;
          $('#prof-courses').append(entry);
        }
        /*for (course in thisInst.courses)
        {
          var courseId = thisInst.courses[course];
          instInfo += '

' + courseId["title"] + '

';
        }*/
        $('#instructor-info').slideToggle();
      })
    }
  }

  // Every time a key is pressed inside the #searchbox, call the getCourseData function
  $('#searchbox').keyup(getCourseData)
  $('#semester, #sort').change(getCourseData)

  // displays information in right pane on click of search result
  $('#results').on('click', 'li.search-result', dispCourseData)
  $('#favs').on('click', 'li.search-result', dispCourseData)
  //$('#disp-profs').on('click', 'a.course-prof', toggleInstructor)

  /* SEB' EXAMPLE
  // $('#results div').click(function () {
  //   console.log($(this).text())
  // })
  $('#results').on('click', 'div.course', function () {
    // window.alert('Handler for .click() called.')
    // console.log(this.course)
    window.alert('You just clicked on the course ' + this.course.title + '!')
  })
  */

  // feedback form toggling
  var toggleFeedback = function() {
    $('#feedback-form').slideToggle()
    if ($('#feedback-toggle').hasClass("active")) {
      $('#feedback-toggle').removeClass("active")
    } else {
      $('#feedback-toggle').addClass("active")
    }
  }

  $('#feedback-toggle').click(toggleFeedback)

  // load the semesters for the dropdown
  $.get('/api/semesters', function (semesters) {
    for (var semesterIndex in semesters) {
      var thisSemester = semesters[semesterIndex]
      $('#semester').append('<option value="' + thisSemester.code + '">' + thisSemester.name + '</select>')
    }
  })

  for (var i = 1.0; i < 5.05; i += 0.1) {
    $('#disp-body').append(''
      + i.toFixed(2)
      + '')
  }
  $('#disp-body').append(' N/A ')

  dispFavorites();
})
<commit_msg>ensure favorites exist<commit_after>// when document loads
$(document).ready(function () {

  // construct local favorites list
  document.favorites = []
  $.get('/api/user/favorites', function(courses) {
    for (var course in courses) {
      document.favorites.push(courses[course]["_id"])
    }
  })

  // get User
  var thisUser = this.User
  $.get('/api/whoami', function (data) {
    $('#nav-netid').html('')
    $('#nav-netid').append(data['netid'])
  })

  // initial displaying favorites
  var dispFavorites = function() {

    // call api to get favorites and display
    $.get('/api/user/favorites', function(courses) {

      $('#favorite-title').css('display', (courses == undefined || courses.length == 0) ? 'none' : 'block')

      $('#favs').html('');
      $('#favorite-title').html('');

      $('#favorite-title').append(courses.length + ' Favorite Course' + (courses.length !== 1 ? 's' : ''))
      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex];

        // append favorite into favs pane
        $('#favs').append(newDOMResult(thisCourse));
      }
    })
  }

  // function for updating search results
  var getCourseData = function () {
    var query = {
      $text: {
        $search: $('#searchbox').val()
      },
      semester: $('#semester').val()
    }

    $.post('/api/courses',
    {
      query: JSON.stringify(query),
      sort: $('#sort').val()
    }, function (courses, status) {
      // Basic error handling
      if (status !== 'success') {
        window.alert('An error occured and your search could not be completed.')
      }

      // clear results
      $('#results').html('')
      $('#search-title').html('')

      $('#search-title').append(courses.length + ' Search Result' + (courses.length !== 1 ? 's' : ''))

      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex]
        $('#results').append(newDOMResult(thisCourse))
      }
    })
  }

  // function for displaying course details
  var dispCourseData = function() {
    $(".search-result").removeClass("active");
    $("#welcome-display-pane").css("display", "none");
    $("#display-pane").css("display", "");
    //document.getElementById("display-pane").style.display = "inline";
    $(this).addClass("active")

    $('#disp-title').html('')
    $('#disp-subtitle').html('')
    $('#disp-profs').html('')
    $('#disp-body').html('')
    $('#evals').html('')
    $('#comments').html('')

    var thisCourse = this.course

    // string for course listings
    var listings =  getListings(thisCourse)

    $('#disp-title').append(thisCourse.title)

    $('#disp-subtitle').append(listings + ' '
                            + (thisCourse.distribution == undefined ? '' : ' ' + thisCourse.distribution + '')
                            + (thisCourse.pdf["required"]  ? ' PDF ONLY'
                            : (thisCourse.pdf["permitted"] ? ' PDF'
                                                                   : ' NPDF'))
                            + (thisCourse.audit ? ' AUDIT' : '')
                            /*+ ' Favorite'*/
                            + (thisCourse.website == undefined ? '' : ' '))

    //$('#fav-button')[0].course = thisCourse;
    //$('#comments').append(thisCourse.evaluations.studentComments)
    // stuff for course evaluations
    var evals = ""
    for (var field in thisCourse.evaluations.scores) {
      var val = thisCourse.evaluations.scores[field]
      evals += '
' + field + '
'
             + '

'
             + val.toFixed(2) + '

' // as percentage of 5
    }
    if (evals == "") {
      $('#evals').append('No course evaluations available.')
    }
    else {
      $('#evals').append(evals)
    }

    // stuff for student comments
    var comments = ""
    for (var studentComment in thisCourse.evaluations.studentComments) {
        var val = thisCourse.evaluations.studentComments[studentComment]
        comments += '
' + val + '
'
    }
    if (comments == "") {
      $('#comments').append('No student comments available.')
    }
    else {
      $('#comments').append(comments)
    }

    var dispbody = ''
    dispbody += '

'
                + '

'
                + '
' + thisCourse.description + '
'
                + (thisCourse.prerequisites == undefined ? '' :
                '
Prerequisites

' + thisCourse.prerequisites + '
')
                + (thisCourse.equivalentcourses == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.equivalentcourses + '
')
                + (thisCourse.otherinformation == undefined ? '' :
                '
Other Information

' + thisCourse.otherinformation + '
')
                + (thisCourse.otherrequirements == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.otherrequirements + '
')
                // '
Classes

' + thisCourse.classes[0] + '
'

    var openClasses = { table: '' };
    var closedClasses = { table: '' };
    var cancelledClasses = { table: '' };

    // Show classes of a course
    var makeClassTable = function(val, classes) {
      classes.table += '
'
                + '' + val['section'] + '	'
                + ''
        for (var day in val.schedule.meetings[0].days) {
          //classes += thisCourse.classes.schedule.meetings[0].days[day]
          classes.table += val.schedule.meetings[0].days[day] + ' '
        }
        classes.table += '	'
        classes.table += (val.schedule.meetings[0] == undefined ? '' :
                  '' + (val.schedule.meetings[0].start_time == undefined ? '' :
                    val.schedule.meetings[0].start_time) + ' - '
                  + (val.schedule.meetings[0].end_time == undefined ? '' :
                    val.schedule.meetings[0].end_time) + '	'
                  + '' + (val.schedule.meetings[0].building == undefined ? '' :
                    val.schedule.meetings[0].building.short_name) + ' '
                  + (val.schedule.meetings[0].room == undefined ? '' :
                    val.schedule.meetings[0].room) + '	'
                )
        classes.table += '' + val['enrollment'] + ' / ' + val['capacity'] + '	'
                  + '
'
    }

    for (var field in thisCourse.classes) {
      var val = thisCourse.classes[field]
      if (val['status'] == "Open") {
        makeClassTable(val, openClasses);
      }
      if (val['status'] == "Cancelled") {
        makeClassTable(val, cancelledClasses);
      }
      if (val['status'] == "Closed") {
        makeClassTable(val, closedClasses);
      }
    }
    dispbody += (openClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Open Classes
' + openClasses.table + '
');
    dispbody += (closedClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Closed Classes
' + closedClasses.table + '
');
    dispbody += (cancelledClasses.table == ''? '' :
              '
' +
              'Section	Days	Time	Room	Enrolled	' +
              '
Cancelled Classes
' + cancelledClasses.table + '
');
    $('#disp-body').append(dispbody)

    for (var instructor in thisCourse.instructors) {
      var name = ''
               + thisCourse.instructors[instructor].name['first'] + ' '
               + thisCourse.instructors[instructor].name['last'] + ''
        if ($('#disp-profs').html() !== '') {
          $('#disp-profs').append(', ')
        }
        $('#disp-profs').append(name)
    }

    // favorite a course
    $("#fav-button").click(function() {
      var thisCourseId = this.course["_id"];
      if (thisUser.favoriteCourses.includes(thisCourseId))
      {
        $.ajax({
          url: '/api/user/favorite',
          type: 'PUT',
          data: {'course': thisCourseId},
          success: function() {dispFavorites();}
        });
      }
      else {
        $.ajax({
          url: '/api/user/favorite',
          type: 'DELETE',
          data: {'course': thisCourseId},
          success: function() {dispFavorites();}
        });
      }
    })

    var prevInstId = 0;
    $('.course-prof').on("click",function(){
      var instId =  $(this).attr("id");
      if (instId != prevInstId)
      {
        $('#instructor-info').hide();
        toggleInstructor(instId);
      }
      else
      {
        $('#instructor-info').slideToggle();
      }
      prevInstId = instId;
    })

    // Instructor page toggling
    var toggleInstructor = function(instId) {
      $('#instructor-info').html('');
      var instInfo = '';

      $.get('/api/instructor/' + instId, function (data) {
        var thisInst = data;
        instInfo += '
 Courses taught by ' + thisInst.name['first'] + ' ' + thisInst.name['last'] + '
';
        instInfo += '
'
        $('#instructor-info').append(instInfo);
        for (var courseIndex in thisInst.courses) {
          var thisCourse = thisInst.courses[courseIndex];
          var entry = $.parseHTML(newInstructorCourseEntry(thisCourse))[0];
          entry.course = thisCourse;
          $('#prof-courses').append(entry);
        }
        /*for (course in thisInst.courses)
        {
          var courseId = thisInst.courses[course];
          instInfo += '

' + courseId["title"] + '

';
        }*/
        $('#instructor-info').slideToggle();
      })
    }
  }

  // Every time a key is pressed inside the #searchbox, call the getCourseData function
  $('#searchbox').keyup(getCourseData)
  $('#semester, #sort').change(getCourseData)

  // displays information in right pane on click of search result
  $('#results').on('click', 'li.search-result', dispCourseData)
  $('#favs').on('click', 'li.search-result', dispCourseData)
  //$('#disp-profs').on('click', 'a.course-prof', toggleInstructor)

  /* SEB' EXAMPLE
  // $('#results div').click(function () {
  //   console.log($(this).text())
  // })
  $('#results').on('click', 'div.course', function () {
    // window.alert('Handler for .click() called.')
    // console.log(this.course)
    window.alert('You just clicked on the course ' + this.course.title + '!')
  })
  */

  // feedback form toggling
  var toggleFeedback = function() {
    $('#feedback-form').slideToggle()
    if ($('#feedback-toggle').hasClass("active")) {
      $('#feedback-toggle').removeClass("active")
    } else {
      $('#feedback-toggle').addClass("active")
    }
  }

  $('#feedback-toggle').click(toggleFeedback)

  // load the semesters for the dropdown
  $.get('/api/semesters', function (semesters) {
    for (var semesterIndex in semesters) {
      var thisSemester = semesters[semesterIndex]
      $('#semester').append('<option value="' + thisSemester.code + '">' + thisSemester.name + '</select>')
    }
  })

  for (var i = 1.0; i < 5.05; i += 0.1) {
    $('#disp-body').append(''
      + i.toFixed(2)
      + '')
  }
  $('#disp-body').append(' N/A ')

  dispFavorites();
})
<|endoftext|>


<commit_before>enyo.kind({
	name: "HermesFileSystemTest",
	kind: "ares.TestSuite",
	debug: false,
	// TODO folderId needs to be created. ENYO-1473
	folderId: "%2FAresTests",
	dirToCreate: "source",
	nodeDir: "%2FAresTests%2Fsource",
	fileToCreate: "App.js",
	nodeFile: "%2FAresTests%2Fsource%2FApp.js",
	registry: null,
	services: null,
	home: null,

	create: function () {
		this.inherited(arguments);
		//this.log("create()");
		this.services = HermesFileSystemTest.services;
		this.home = HermesFileSystemTest.home;
	},
	/**
	* get Services from registry
	*/
	testGetServicesFromRegistry: function() {
		this.log("Begin called in testGetServicesFromRegitry.");
		this.registry = ServiceRegistry.instance;
		this.registry._reloadServices(enyo.bind(this, "cbReloadServices"));

	},
	cbReloadServices: function(inError) {
		this.log("Begin called in cbReloadServices.");
		if (inError) {
			this.finish("No services loaded!");
		} else {
			this.services = this.registry.services;
			HermesFileSystemTest.services = this.services;
			if (this.debug) {
				this.log("HermesFileSystemTest.services: ");
				console.dir(HermesFileSystemTest.services);
			}
			if(this.services.length > 0) {
				this.finish();
			} else {
				this.finish("No Home service found.");
			}
		}
	},
	/**
	* get Home service from services
	*/
	testGetHomeFromServices: function() {
		this.log("Begin called in testGetHomeFromServices.");
		var h = this.services.filter(function(s) {
			if (this.debug) {
				this.log("service.conf.id: "+s.conf.id);
			}
			return s.conf.id === "home";
		});
		if (this.debug) {
			this.log("home service: ");
			console.dir(h);
		}
		this.home = h;
		HermesFileSystemTest.home = this.home;
		if(h.length > 0) {
			this.finish();
		} else {
			this.finish("No Home service found.");
		}
	},
	/**
	* HermesFileSystem API
	*/
	testPropfindAndCreateFolder: function() {
		this.log("Begin called in testPropfindAndCreateFolder.");
		/**
		*	PROPFIND verb used to listFiles of a folderId
		*/
		var service = this.home[0];
		var req = service.impl.propfind(this.folderId, 1);
		req.response(this, function(inSender, inResponse) {
			var self = this;
			var r = inResponse.children.filter(function(node){
				return node.name === this.dirToCreate;
			});
			if (r.length !== 0) {
				this.finish("folder already exists.");
			} else {
				/**
				* MKCOL verb
				*/
				// want to create @HOME@/AresTests/source directory
				var req2 = service.impl.createFolder(this.folderId, this.dirToCreate);
				req2.response(function(inSender, inResponse) {
					if (this.debug) {
						this.log(inResponse);
					}
					self.finish();
				});
				req2.error(this, function(inSender, inError) {
					this.log(inError);
					self.finish("create folder error: "+inError);
				});
			}
		});
		req.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("propfind create folder error: "+inError);
		});
	},

	testPropfindAndCreateFile: function() {
		console.log("Begin called in testPropfindAndCreateFile.");
		/**
		*	PROPFIND verb used to listFiles of a folderId
		*/
		var service = this.home[0];
		var req = service.impl.propfind(this.nodeDir, 1);
		req.response(this, function(inSender, inResponse) {
			var self = this;
			if (this.debug) {
				this.log("profind/create file inResponse.children: "+JSON.stringify(inResponse));
			}
			var r = inResponse.children.filter(function(node){
				return node.name === this.dirToCreate;
			});
			if (r.length !== 0) {
				this.finish("file already exists.");
			} else {
				var content = {
					title: "created by the test suite"
				};
				/**
				* PUT Verb
				*/
				// want to create @HOME@/AresTests/source/App.js file
				var req2 = service.impl.createFile(this.nodeDir, this.fileToCreate, content);
				req2.response(self, function(inSender, inResponse) {
					if (this.debug) {
						this.log("create File inResponse: "+JSON.stringify(inResponse));
					}
					self.finish();
				});
				req2.error(this, function(inSender, inError) {
					if (this.debug) {
						this.log(inError);
					}
					self.finish("create file error: "+inError);
				});
			}
		});
		req.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("propfind create file error: "+inError);
		});
	},
	testDeleteFile: function() {
		console.log("Begin called in testDeleteFile.");
		var service = this.home[0];
		/**
		* DELETE verb
		*/
		// want to delete @HOME@/AresTests/source/App.js file
		// nodeFile: "%2FAresTests%2Fsource%2FApp.js"
		var req2 = service.impl.remove(this.nodeFile);
		req2.response(this, function(inSender, inResponse) {
			if (this.debug) {
				this.log("delete File inResponse: "+JSON.stringify(inResponse));
			}
			this.finish();
		});
		req2.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("delete File error: "+inError);
		});
	},
	testDeleteFolder: function() {
		console.log("Begin called in testDeleteFolder.");
		var service = this.home[0];
		/**
		* DELETE verb
		*/
		// want to delete @HOME@/AresTests/source directory
		// nodeDir: "%2FAresTests%2Fsource"
		var req = service.impl.remove(this.nodeDir);
		req.response(this, function(inSender, inResponse) {
		if (this.debug) {
				this.log("delete Folder inResponse: "+JSON.stringify(inResponse));
		}		this.finish();
		});
		req.error(self, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("delete Folder error: "+inError);
		});
	},
	statics: {
		services: null,
		home: null
	}
});<commit_msg>ENYO-1472:  Ares testSuite: Display into a Ares Test window results of the test suite . HermesFileSytemTest.js broken after master integration due to service structure change in ServiceRegistry; field conf changed in config - Enyo-DCO-1.1-Signed-off-by: Marie-Antoinette de Bonis-Hamelin (Marian) marie-antoinette.de-bonis-hamelin@hp.com<commit_after>enyo.kind({
	name: "HermesFileSystemTest",
	kind: "ares.TestSuite",
	debug: false,
	// TODO folderId needs to be created. ENYO-1473
	folderId: "%2FAresTests",
	dirToCreate: "source",
	nodeDir: "%2FAresTests%2Fsource",
	fileToCreate: "App.js",
	nodeFile: "%2FAresTests%2Fsource%2FApp.js",
	registry: null,
	services: null,
	home: null,

	create: function () {
		this.inherited(arguments);
		//this.log("create()");
		this.services = HermesFileSystemTest.services;
		this.home = HermesFileSystemTest.home;
	},
	/**
	* get Services from registry
	*/
	testGetServicesFromRegistry: function() {
		this.log("Begin called in testGetServicesFromRegitry.");
		this.registry = ServiceRegistry.instance;
		this.registry._reloadServices(enyo.bind(this, "cbReloadServices"));

	},
	cbReloadServices: function(inError) {
		this.log("Begin called in cbReloadServices.");
		if (inError) {
			this.finish("No services loaded!");
		} else {
			this.services = this.registry.services;
			HermesFileSystemTest.services = this.services;
			if (this.debug) {
				this.log("HermesFileSystemTest.services: ");
				console.dir(HermesFileSystemTest.services);
			}
			if(this.services.length > 0) {
				this.finish();
			} else {
				this.finish("No Home service found.");
			}
		}
	},
	/**
	* get Home service from services
	*/
	testGetHomeFromServices: function() {
		this.log("Begin called in testGetHomeFromServices.");
		var h = this.services.filter(function(s) {
			if (this.debug) {
				this.log("service.conf.id: "+s.conf.id);
			}
			return s.config.id === "home";
		});
		if (this.debug) {
			this.log("home service: ");
			console.dir(h);
		}
		this.home = h;
		HermesFileSystemTest.home = this.home;
		if(h.length > 0) {
			this.finish();
		} else {
			this.finish("No Home service found.");
		}
	},
	/**
	* HermesFileSystem API
	*/
	testPropfindAndCreateFolder: function() {
		this.log("Begin called in testPropfindAndCreateFolder.");
		/**
		*	PROPFIND verb used to listFiles of a folderId
		*/
		var service = this.home[0];
		var req = service.impl.propfind(this.folderId, 1);
		req.response(this, function(inSender, inResponse) {
			var self = this;
			var r = inResponse.children.filter(function(node){
				return node.name === this.dirToCreate;
			});
			if (r.length !== 0) {
				this.finish("folder already exists.");
			} else {
				/**
				* MKCOL verb
				*/
				// want to create @HOME@/AresTests/source directory
				var req2 = service.impl.createFolder(this.folderId, this.dirToCreate);
				req2.response(function(inSender, inResponse) {
					if (this.debug) {
						this.log(inResponse);
					}
					self.finish();
				});
				req2.error(this, function(inSender, inError) {
					this.log(inError);
					self.finish("create folder error: "+inError);
				});
			}
		});
		req.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("propfind create folder error: "+inError);
		});
	},

	testPropfindAndCreateFile: function() {
		console.log("Begin called in testPropfindAndCreateFile.");
		/**
		*	PROPFIND verb used to listFiles of a folderId
		*/
		var service = this.home[0];
		var req = service.impl.propfind(this.nodeDir, 1);
		req.response(this, function(inSender, inResponse) {
			var self = this;
			if (this.debug) {
				this.log("profind/create file inResponse.children: "+JSON.stringify(inResponse));
			}
			var r = inResponse.children.filter(function(node){
				return node.name === this.dirToCreate;
			});
			if (r.length !== 0) {
				this.finish("file already exists.");
			} else {
				var content = {
					title: "created by the test suite"
				};
				/**
				* PUT Verb
				*/
				// want to create @HOME@/AresTests/source/App.js file
				var req2 = service.impl.createFile(this.nodeDir, this.fileToCreate, content);
				req2.response(self, function(inSender, inResponse) {
					if (this.debug) {
						this.log("create File inResponse: "+JSON.stringify(inResponse));
					}
					self.finish();
				});
				req2.error(this, function(inSender, inError) {
					if (this.debug) {
						this.log(inError);
					}
					self.finish("create file error: "+inError);
				});
			}
		});
		req.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("propfind create file error: "+inError);
		});
	},
	testDeleteFile: function() {
		console.log("Begin called in testDeleteFile.");
		var service = this.home[0];
		/**
		* DELETE verb
		*/
		// want to delete @HOME@/AresTests/source/App.js file
		// nodeFile: "%2FAresTests%2Fsource%2FApp.js"
		var req2 = service.impl.remove(this.nodeFile);
		req2.response(this, function(inSender, inResponse) {
			if (this.debug) {
				this.log("delete File inResponse: "+JSON.stringify(inResponse));
			}
			this.finish();
		});
		req2.error(this, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("delete File error: "+inError);
		});
	},
	testDeleteFolder: function() {
		console.log("Begin called in testDeleteFolder.");
		var service = this.home[0];
		/**
		* DELETE verb
		*/
		// want to delete @HOME@/AresTests/source directory
		// nodeDir: "%2FAresTests%2Fsource"
		var req = service.impl.remove(this.nodeDir);
		req.response(this, function(inSender, inResponse) {
		if (this.debug) {
				this.log("delete Folder inResponse: "+JSON.stringify(inResponse));
		}		this.finish();
		});
		req.error(self, function(inSender, inError) {
			if (this.debug) {
				this.log(inError);
			}
			this.finish("delete Folder error: "+inError);
		});
	},
	statics: {
		services: null,
		home: null
	}
});<|endoftext|>


<commit_before>
var test = require('tape')
require('rewire-global').enable()
const sinon = require('sinon')
const proxyquire = require('proxyquire').noCallThru()

const readMessageFromQueueStub = sinon.stub()
const queue = sinon.stub().returns({
  readMessageFromQueue: readMessageFromQueueStub
})

const consumeMessages = proxyquire('../../../messages/consumeMessages', {
  'node-queue-adapter': queue,
  './deleteMessage': sinon.stub().returns(Promise.resolve()),
  './handleMessage': sinon.stub().returns(Promise.resolve())
})

// overwrite original function to be able to break the eternal loop in the test
const readMessage = consumeMessages.readMessage
const readMessageStub = sinon.stub()
consumeMessages.__set__('readMessage', readMessageStub)

test('read message without body should call read message again', t => {
  t.plan(1)
  readMessageFromQueueStub.returns(Promise.resolve({}))

  readMessage()
    .then(res => t.equal(readMessageStub.called, true))
})

test('read message without message should call read message again', t => {
  t.plan(1)
  readMessageFromQueueStub.returns(Promise.resolve())

  readMessage()
    .then(res => t.equal(readMessageStub.called, true))
})

test('read message with incorrect body should call read message again', t => {
  t.plan(1)
  readMessageFromQueueStub.returns(Promise.resolve({
    body: ''
  }))

  readMessage()
    .then(res => t.equal(readMessageStub.called, true)
  )
})

test('read message with correct body should call read message again', t => {
  t.plan(1)
  readMessageFromQueueStub.returns(Promise.resolve({
    body: '{}'
  }))

  readMessage()
    .then(res => t.equal(readMessageStub.called, true))
})
<commit_msg>added tests for deleting messages<commit_after>
var test = require('tape')
require('rewire-global').enable()
const sinon = require('sinon')
const proxyquire = require('proxyquire').noCallThru()

const readMessageFromQueueStub = sinon.stub()
const deleteMessageFromQueue = sinon.stub()

const queue = sinon.stub().returns({
  readMessageFromQueue: readMessageFromQueueStub,
  deleteMessageFromQueue
})

const consumeMessages = proxyquire('../../../messages/consumeMessages', {
  'node-queue-adapter': queue,
  './handleMessage': sinon.stub().returns(Promise.resolve())
})

// overwrite original function to be able to break the eternal loop in the test
const readMessage = consumeMessages.readMessage
const readMessageStub = sinon.stub()
consumeMessages.__set__('readMessage', readMessageStub)

function reset() {
  readMessageFromQueueStub.reset()
  deleteMessageFromQueue.reset()
}

test('read message without body should call read message again', t => {
  t.plan(2)
  reset()
  readMessageFromQueueStub.returns(Promise.resolve({}))

  readMessage()
    .then(res => {
      t.equal(readMessageStub.called, true)
      t.equal(deleteMessageFromQueue.called, false)
    })
})

test('read message without message should call read message again', t => {
  t.plan(2)
  reset()

  readMessageFromQueueStub.returns(Promise.resolve())

  readMessage()
    .then(res => {
      t.equal(readMessageStub.called, true)
      t.equal(deleteMessageFromQueue.called, false)
    })
})

test('read message with incorrect body should call read message again', t => {
  t.plan(2)
  reset()

  readMessageFromQueueStub.returns(Promise.resolve({
    body: ''
  }))

  readMessage()
    .then(res => {
      t.equal(readMessageStub.called, true)
      t.equal(deleteMessageFromQueue.called, false) // its ok to keep these messages. They will eventually be moved to the error queue where they will be reported as incorrect messages
    })
})

test('read message with correct body should call read message again', t => {
  t.plan(2)
  reset()

  readMessageFromQueueStub.returns(Promise.resolve({
    body: '{}'
  }))

  readMessage()
    .then(res => {
      t.equal(readMessageStub.called, true)
      t.equal(deleteMessageFromQueue.called, true)
    })
})
<|endoftext|>


<commit_before>var q = require('q');
var Jasmine = require('jasmine');
var SpecReporter = require('jasmine-spec-reporter');
var jrunner = new Jasmine();
var ermrestUtils = require('ermrest-data-utils');

// Util function to create a catalog before running all specs
// Returns a promise
var createCatalog = function() {
	var defer = q.defer();

	// make http request to create a catalog to be used across all specs
	ermrestUtils.importData({
        setup: { catalog: {} },
        url: process.env.ERMREST_URL,
        authCookie: process.env.AUTH_COOKIE
    }).then(function (data) {
    	process.env.DEFAULT_CATALOG = data.catalogId;
	    defer.resolve(data.catalogId);
    }, function (err) {
	    defer.reject(err);
    });

	return defer.promise;
};
exports.createCatalog = createCatalog;

// Util function to delete a catalog if provided or uses process.env.DEFAULT_CATALOG after running all specs
// Returns a promise
var deleteCatalog = function(catalogId) {
	var defer = q.defer();
	catalogId = catalogId || process.env.DEFAULT_CATALOG;
	if (catalogId) {
		ermrestUtils.tear({
	        setup: { catalog : { } },
	        catalogId: catalogId,
	        url:  process.env.ERMREST_URL ,
	        authCookie : process.env.AUTH_COOKIE
	    }).then(function(data) {
		  	defer.resolve();
	    }, function(err) {
	        console.log("Unable to delete catalog");
		    defer.reject(err);
	    });
	} else {
		defer.resolve("no catalogId found");
	}

	return defer.promise;
};
exports.deleteCatalog = deleteCatalog

// Start running the test specs
// Accepts a config json
// Creates a catalog and then runs the specs as mentioned in the config file
// Deletes the created catalog once all specs have been executed
exports.run = function(config) {

	// Load the configuration
	jrunner.loadConfig(config);

	// Remove default reporter logs
	jrunner.configureDefaultReporter({ print: function() { } });

	// Add Jasmine  specReporter
	jrunner.addReporter(new SpecReporter());

	// Set timeout to a large value
	jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;

	jrunner.onComplete(function(passed) {
		console.log("Test suite " + (passed ? "passed" : "failed"));
		deleteCatalog().done(function() {
			if (!passed) process.exit(1);
		});
	});

	// Create a catalog and then
	// Execute the specs mentioned in the config file jasmine.json in /support folder
	createCatalog().then(function() {
		jrunner.execute();
	}, function(err) {
		console.log("Unable to create default catalog");
		process.exit(1);
	}).catch(function(err) {
		process.exit(1);
	});
};<commit_msg>Change timeout interval for test cases to allow late server requests.<commit_after>var q = require('q');
var Jasmine = require('jasmine');
var SpecReporter = require('jasmine-spec-reporter');
var jrunner = new Jasmine();
var ermrestUtils = require('ermrest-data-utils');

// Util function to create a catalog before running all specs
// Returns a promise
var createCatalog = function() {
	var defer = q.defer();

	// make http request to create a catalog to be used across all specs
	ermrestUtils.importData({
        setup: { catalog: {} },
        url: process.env.ERMREST_URL,
        authCookie: process.env.AUTH_COOKIE
    }).then(function (data) {
    	process.env.DEFAULT_CATALOG = data.catalogId;
	    defer.resolve(data.catalogId);
    }, function (err) {
	    defer.reject(err);
    });

	return defer.promise;
};
exports.createCatalog = createCatalog;

// Util function to delete a catalog if provided or uses process.env.DEFAULT_CATALOG after running all specs
// Returns a promise
var deleteCatalog = function(catalogId) {
	var defer = q.defer();
	catalogId = catalogId || process.env.DEFAULT_CATALOG;
	if (catalogId) {
		ermrestUtils.tear({
	        setup: { catalog : { } },
	        catalogId: catalogId,
	        url:  process.env.ERMREST_URL ,
	        authCookie : process.env.AUTH_COOKIE
	    }).then(function(data) {
		  	defer.resolve();
	    }, function(err) {
	        console.log("Unable to delete catalog");
		    defer.reject(err);
	    });
	} else {
		defer.resolve("no catalogId found");
	}

	return defer.promise;
};
exports.deleteCatalog = deleteCatalog

// Start running the test specs
// Accepts a config json
// Creates a catalog and then runs the specs as mentioned in the config file
// Deletes the created catalog once all specs have been executed
exports.run = function(config) {

	// Load the configuration
	jrunner.loadConfig(config);

	// Remove default reporter logs
	jrunner.configureDefaultReporter({ print: function() { } });

	// Add Jasmine  specReporter
	jrunner.addReporter(new SpecReporter());

	// Set timeout to a large value
	jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;

	jrunner.onComplete(function(passed) {
		console.log("Test suite " + (passed ? "passed" : "failed"));
		deleteCatalog().done(function() {
			if (!passed) process.exit(1);
		});
	});

	// Create a catalog and then
	// Execute the specs mentioned in the config file jasmine.json in /support folder
	createCatalog().then(function() {
		jrunner.execute();
	}, function(err) {
		console.log("Unable to create default catalog");
		process.exit(1);
	}).catch(function(err) {
		process.exit(1);
	});
};<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import CSSModules from 'react-css-modules';
import classNames from 'classnames/bind';

import globe from './globe.svg';
import css from './MobileSectionPanel.css';

import macros from '../macros'
import WeekdayBoxes from './WeekdayBoxes';
import LocationLinks from './LocationLinks';

const cx = classNames.bind(css);

// TODO:
// Waitlist UI/wording could be cleaned up/simplified a bit.

// MobileSectionPanel page component
class MobileSectionPanel extends React.Component {

  render() {
    // Add another row for seats remaining on the waitlist if any exist.
    let waitlistRow = null;
    const hasWaitList = this.props.section.getHasWaitList();
    if (hasWaitList) {
      waitlistRow = (

          Wait

            {this.props.section.waitRemaining}/{this.props.section.waitCapacity} Waitlist Seats Avalible

      );
    }

    // Create the 4:35 - 5:40 pm string.
    const meetingMoments = this.props.section.getAllMeetingMoments();
    const times = [];
    meetingMoments.forEach((time) => {
      const startString = time.start.format('h:mm');
      const endString = time.end.format('h:mm a');
      const combinedString = `${startString} - ${endString}`;
      if (!times.includes(combinedString)) {
        times.push(combinedString);
      }
    });

    let fullTimesString;
    if (times.length > 0) {
      fullTimesString = times.join(', ');
    }
    else {
      fullTimesString = 'TBA';
    }

    // Add a row for exam, if the section has an exam.
    let examRow = null;
    if (this.props.section.getHasExam()) {
      const examMoments = this.props.section.getExamMoments();
      if (examMoments) {
        examRow = (

            Exam

              {examMoments.start.format('MMMM Do @ h:mm a')}

      );
      }
    }

    let timeInTitle;
    if (meetingMoments.length > 0) {
      timeInTitle = meetingMoments[0].start.format('h:mm a');
    }
    else {
      timeInTitle = "TBA"
    }

    return (

{`${macros.stripMiddleName(this.props.section.getProfs()[0])} @ ${timeInTitle}`}

              CRN
              {this.props.section.crn}

              Profs
              {this.props.section.getProfs().join(', ')}

              Place

                <LocationLinks section={ this.props.section } />

              Times

                {fullTimesString}

              Days

                <WeekdayBoxes section={ this.props.section } />

            {examRow}

              Seats

                {this.props.section.seatsRemaining}/{this.props.section.seatsCapacity} Avalible

            {waitlistRow}

    );
  }

}

MobileSectionPanel.propTypes = {
  section: PropTypes.object.isRequired,
};

export default CSSModules(MobileSectionPanel, css);
<commit_msg>Fixed when to show waitlist on mobile<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import CSSModules from 'react-css-modules';
import classNames from 'classnames/bind';

import globe from './globe.svg';
import css from './MobileSectionPanel.css';

import macros from '../macros'
import WeekdayBoxes from './WeekdayBoxes';
import LocationLinks from './LocationLinks';

const cx = classNames.bind(css);

// TODO:
// Waitlist UI/wording could be cleaned up/simplified a bit.

// MobileSectionPanel page component
class MobileSectionPanel extends React.Component {

  // This is different than the one in ClassPanel.js because this can show and hide the waitlist based on a per-section basis
  // and ClassPanel.js is show it for all classes or none.
  shouldShowWaitlist() {
    if (this.props.section.getHasWaitList() && this.props.section.seatsRemaining < 10) {
      return true;
    }
    else {
      return false;
    }
  }

  render() {
    // Add another row for seats remaining on the waitlist if any exist.
    let waitlistRow = null;
    const hasWaitList = this.shouldShowWaitlist();
    if (hasWaitList) {
      waitlistRow = (

          Wait

            {this.props.section.waitRemaining}/{this.props.section.waitCapacity} Waitlist Seats Avalible

      );
    }

    // Create the 4:35 - 5:40 pm string.
    const meetingMoments = this.props.section.getAllMeetingMoments();
    const times = [];
    meetingMoments.forEach((time) => {
      const startString = time.start.format('h:mm');
      const endString = time.end.format('h:mm a');
      const combinedString = `${startString} - ${endString}`;
      if (!times.includes(combinedString)) {
        times.push(combinedString);
      }
    });

    let fullTimesString;
    if (times.length > 0) {
      fullTimesString = times.join(', ');
    }
    else {
      fullTimesString = 'TBA';
    }

    // Add a row for exam, if the section has an exam.
    let examRow = null;
    if (this.props.section.getHasExam()) {
      const examMoments = this.props.section.getExamMoments();
      if (examMoments) {
        examRow = (

            Exam

              {examMoments.start.format('MMMM Do @ h:mm a')}

      );
      }
    }

    let timeInTitle;
    if (meetingMoments.length > 0) {
      timeInTitle = meetingMoments[0].start.format('h:mm a');
    }
    else {
      timeInTitle = "TBA"
    }

    return (

{`${macros.stripMiddleName(this.props.section.getProfs()[0])} @ ${timeInTitle}`}

              CRN
              {this.props.section.crn}

              Profs
              {this.props.section.getProfs().join(', ')}

              Place

                <LocationLinks section={ this.props.section } />

              Times

                {fullTimesString}

              Days

                <WeekdayBoxes section={ this.props.section } />

            {examRow}

              Seats

                {this.props.section.seatsRemaining}/{this.props.section.seatsCapacity} Avalible

            {waitlistRow}

    );
  }

}

MobileSectionPanel.propTypes = {
  section: PropTypes.object.isRequired,
};

export default CSSModules(MobileSectionPanel, css);
<|endoftext|>


<commit_before>import React from 'react';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import SaveIcon from '@material-ui/icons/Save';
import TextField from '@material-ui/core/TextField';
import { Formik } from 'formik';
import { withStyles } from '@material-ui/core/styles';
import { Mutation } from 'react-apollo';
import gql from 'graphql-tag';
import { allCitiesQuery } from '.';

const styles = theme => ({
  textField: {
    marginLeft: -theme.spacing.unit,
    // marginRight: theme.spacing.unit,
    marginBottom: -7,
    marginTop: -7,
  },
  textFieldInput: {
    padding: '10px 10px',
  },
});

export const updateCityMutation = gql`
  mutation updateCityMutation($id: ID!, $name: String!) {
    updateCity(id: $id, name: $name) {
      id
      name
    }
  }
`;

const onSubmitEdit = (updateCity, handleCloseEdit) => (values, { setSubmitting }) => {
  updateCity({
    variables: {
      id: values.id,
      name: values.name,
    },
  })
    .then(response => {
      console.log(`Update City Mutation response: `);
      console.log(response);
      setSubmitting(false);
      handleCloseEdit();
    })
    .catch(error => {
      // Something went wrong, such as incorrect password, or no network
      // available, etc.
      console.error(error);
    });
};

const EditListItem = ({ city, handleCloseEdit, classes }) => {
  return (
    <Mutation
      mutation={updateCityMutation}
      update={(proxy, { data: { updateCity } }) => {
        const data = proxy.readQuery({ query: allCitiesQuery });

        const index = data.cities.map(c => c.id).indexOf(updateCity.id);
        data.cities[index].name = updateCity.name;

        proxy.writeQuery({ query: allCitiesQuery, data });
      }}
    >
      {updateCity => (
        <Formik initialValues={city} onSubmit={onSubmitEdit(updateCity, handleCloseEdit)}>
          {({ handleSubmit, handleChange, handleBlur, isSubmitting, values }) => (
            <React.Fragment>
              <ListItemText>
                <TextField
                  name="name"
                  id="outlined-bare"
                  className={classes.textField}
                  margin="normal"
                  variant="outlined"
                  inputProps={{
                    className: classes.textFieldInput,
                  }}
                  value={values.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                />
              </ListItemText>
              <ListItemSecondaryAction>
                <IconButton
                  onClick={handleSubmit}
                  disabled={isSubmitting}
                  aria-label="Salvar cidade"
                >
                  <SaveIcon color="primary" />
                </IconButton>
                <IconButton
                  onClick={handleCloseEdit}
                  disabled={isSubmitting}
                  aria-label="Cancelar edição"
                >
                  <CloseIcon />
                </IconButton>
              </ListItemSecondaryAction>
            </React.Fragment>
          )}
        </Formik>
      )}
    </Mutation>
  );
};

export default withStyles(styles)(EditListItem);
<commit_msg>Fix editing city item to focus input on click<commit_after>import React from 'react';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import SaveIcon from '@material-ui/icons/Save';
import TextField from '@material-ui/core/TextField';
import { Formik } from 'formik';
import { withStyles } from '@material-ui/core/styles';
import { Mutation } from 'react-apollo';
import gql from 'graphql-tag';
import { allCitiesQuery } from '.';

const styles = theme => ({
  textField: {
    marginLeft: -theme.spacing.unit,
    // marginRight: theme.spacing.unit,
    marginBottom: -7,
    marginTop: -7,
  },
  textFieldInput: {
    padding: '10px 10px',
  },
});

export const updateCityMutation = gql`
  mutation updateCityMutation($id: ID!, $name: String!) {
    updateCity(id: $id, name: $name) {
      id
      name
    }
  }
`;

const onSubmitEdit = (updateCity, handleCloseEdit) => (values, { setSubmitting }) => {
  updateCity({
    variables: {
      id: values.id,
      name: values.name,
    },
  })
    .then(response => {
      console.log(`Update City Mutation response: `);
      console.log(response);
      setSubmitting(false);
      handleCloseEdit();
    })
    .catch(error => {
      // Something went wrong, such as incorrect password, or no network
      // available, etc.
      console.error(error);
    });
};

const EditListItem = ({ city, handleCloseEdit, classes }) => {
  return (
    <Mutation
      mutation={updateCityMutation}
      update={(proxy, { data: { updateCity } }) => {
        const data = proxy.readQuery({ query: allCitiesQuery });

        const index = data.cities.map(c => c.id).indexOf(updateCity.id);
        data.cities[index].name = updateCity.name;

        proxy.writeQuery({ query: allCitiesQuery, data });
      }}
    >
      {updateCity => (
        <Formik initialValues={city} onSubmit={onSubmitEdit(updateCity, handleCloseEdit)}>
          {({ handleSubmit, handleChange, handleBlur, isSubmitting, values }) => (
            <React.Fragment>
              <ListItemText>
                <TextField
                  name="name"
                  id="outlined-bare"
                  className={classes.textField}
                  margin="normal"
                  variant="outlined"
                  inputProps={{
                    className: classes.textFieldInput,
                    autoFocus: true,
                  }}
                  value={values.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                />
              </ListItemText>
              <ListItemSecondaryAction>
                <IconButton
                  onClick={handleSubmit}
                  disabled={isSubmitting}
                  aria-label="Salvar cidade"
                >
                  <SaveIcon color="primary" />
                </IconButton>
                <IconButton
                  onClick={handleCloseEdit}
                  disabled={isSubmitting}
                  aria-label="Cancelar edição"
                >
                  <CloseIcon />
                </IconButton>
              </ListItemSecondaryAction>
            </React.Fragment>
          )}
        </Formik>
      )}
    </Mutation>
  );
};

export default withStyles(styles)(EditListItem);
<|endoftext|>


<commit_before>import moment from 'moment';
import { test } from 'qunit';
import moduleForAcceptance from 'hospitalrun/tests/helpers/module-for-acceptance';
import runWithPouchDump from 'hospitalrun/tests/helpers/run-with-pouch-dump';
import select from 'hospitalrun/tests/helpers/select';
import selectDate from 'hospitalrun/tests/helpers/select-date';
import typeAheadFillIn from 'hospitalrun/tests/helpers/typeahead-fillin';
import { waitToAppear } from 'hospitalrun/tests/helpers/wait-to-appear';
import { authenticateUser } from 'hospitalrun/tests/helpers/authenticate-user';

moduleForAcceptance('Acceptance | inventory');

test('visiting /inventory', function(assert) {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory');
    findWithAssert('button:contains(new request)');
    findWithAssert('button:contains(+ Inventory Received)');
    findWithAssert('p:contains(No requests found. )');
    findWithAssert('a:contains(Create a new request?)');
  });
});

test('Adding a new inventory item', (assert) => {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory/edit/new');
    assert.equal(currentURL(), '/inventory/edit/new');

    await fillIn('.test-inv-name input', 'Biogesic');
    await select('.test-inv-rank', 'B');
    await fillIn('textarea', 'Biogesic nga medisina');
    await select('.test-inv-type', 'Medication');
    await fillIn('.test-inv-cross input', '2600');
    await fillIn('.test-inv-reorder input', '100');
    await fillIn('.test-inv-price input', '5');
    await select('.test-inv-dist-unit', 'tablet');
    await fillIn('.test-inv-quantity input', '1000');
    await fillIn('.test-inv-cost input', '4000');
    await select('.test-inv-unit', 'tablet');
    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Inventory Item Saved', 'Inventory Item was saved successfully');

    await click('button:contains(Ok)');
    findWithAssert('button:contains(Add Purchase)');
    findWithAssert('button:contains(Update)');
    findWithAssert('button:contains(Return)');

    await click('button:contains(Add Purchase)');
    await waitToAppear('.modal-dialog');
    await fillIn('.test-inv-quantity div div input', 18);
    await fillIn('.test-inv-cost div input', 2);
    await fillIn('.test-vendor div span input:eq(1)', 'fakeVendor');
    await click('.modal-footer .btn-primary');
    assert.dom('div.alert.alert-danger.alert-dismissible').doesNotExist('Quantity error does not appear');
    assert.dom($('.test-location-quantity')[0]).hasText('1018', 'Location quantity is correct after new purchase');
    assert.dom('.test-inv-quantity p').hasText('1018', 'Item total quantity is correct after new purchase');

    await click('button:contains(Return)');
    assert.equal(currentURL(), '/inventory/listing');
    assert.dom('tr').exists({ count: 2 }, 'One item is listed');
  });
});

test('Items with negative quantites should not be saved', (assert) => {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory/edit/new');
    assert.equal(currentURL(), '/inventory/edit/new');

    await fillIn('.test-inv-name input', 'Biogesic');
    await select('.test-inv-rank', 'B');
    await fillIn('textarea', 'Biogesic nga medisina');
    await select('.test-inv-type', 'Medication');
    await fillIn('.test-inv-cross input', '2600');
    await fillIn('.test-inv-reorder input', '100');
    await fillIn('.test-inv-price input', '5');
    await select('.test-inv-dist-unit', 'tablet');
    await fillIn('.test-inv-quantity input', '-1000');
    await fillIn('.test-inv-cost input', '4000');
    await select('.test-inv-unit', 'tablet');
    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');

    assert.dom('.modal-title').hasText(
      'Warning!!!!',
      'Inventory Item with negative quantity should not be saved.'
    );

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory/edit/new');
    findWithAssert('button:contains(Add)');
    findWithAssert('button:contains(Cancel)');
    assert.dom('.test-inv-quantity .help-block').hasText(
      'not a valid number',
      'Error message should be present for invalid quantities'
    );
  });
});

test('Visiting /inventory/barcode', (assert) => {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/listing');
    assert.equal(currentURL(), '/inventory/listing');

    await click('a:contains(Barcode)');
    assert.equal(currentURL(), '/inventory/barcode/igbmk5zf_is');
    findWithAssert('.panel-body img[src^="data:image"]');
  });
});

test('Deleting the last inventory item', (assert) => {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/listing');
    assert.equal(currentURL(), '/inventory/listing');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Item', 'Deleting confirmation.');

    await click('.modal-content button:contains(Delete)');
    await waitToAppear('.panel-body .alert-info');
    assert.equal(currentURL(), '/inventory/listing');
    findWithAssert('a:contains(Create a new record?)');
  });
});

test('Creating a new inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/request/new');
    assert.equal(currentURL(), '/inventory/request/new');

    await typeAheadFillIn('.test-inv-item', 'Biogesic - m00001 (1000 available)');
    await fillIn('.test-inv-quantity input', 500);
    await typeAheadFillIn('.test-delivery-location', 'Harare');
    await typeAheadFillIn('.test-delivery-aisle', 'C100');
    await typeAheadFillIn('.test-bill-to', 'Accounts Dept');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Request Updated', 'New request has been saved');

    await click('button:contains(Ok)');
    findWithAssert('button:contains(Fulfill)');
    findWithAssert('button:contains(Cancel)');

    await click('button:contains(Cancel)');
    assert.equal(currentURL(), '/inventory');
    assert.dom('tr').exists({ count: 3 }, 'Two requests are now displayed');
  });
});

test('Fulfilling an inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory');
    let tableRows = find('tr').length;
    assert.equal(tableRows, 2, 'One request not fulfilled');

    await click('button:contains(Fulfill)');
    findWithAssert('button:contains(Fulfill)');
    findWithAssert('button:contains(Cancel)');

    await waitToAppear('.inventory-location option:contains(No Location)');
    await click('button:contains(Fulfill)');
    await waitToAppear('.modal-dialog');

    let modalTitle = find('.modal-title');
    assert.equal(modalTitle.text(), 'Request Fulfilled', 'Inventory request has been fulfilled');

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory');
  });
});

test('Deleting an inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one request');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Item', 'Deleting confirmation');

    await click('.modal-content button:contains(Delete)');
    await waitToAppear('.panel-body .alert-info');
    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 0, 'Request was deleted');
  });
});

test('User with add_inventory_request and without fulfill_inventory rights should not be able to delete others\' requests', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser({
      name: 'nurse.mgr',
      roles: ['Nurse Manager', 'user'],
      role: 'Nurse Manager'
    });
    await visit('/inventory');

    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 0, 'User doesn\'t see Delete button');
  });
});

test('Receiving inventory', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/batch/new');
    assert.equal(currentURL(), '/inventory/batch/new');

    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await fillIn('.test-invoice-number input', 'P2345');
    await typeAheadFillIn('.test-inv-item', 'Biogesic - m00001');
    await fillIn('.test-inv-quantity input', 500);
    await fillIn('.test-inv-cost input', '2000');
    await waitToAppear('.inventory-distribution-unit');
    await click('button:contains(Save)');
    await waitToAppear('.modal-title');

    let modalTitle = find('.modal-title');
    assert.equal(modalTitle.text(), 'Inventory Purchases Saved', 'Inventory has been received');

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory/listing');
  });
});

test('Searching inventory', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');

    await fillIn('[role="search"] div input', 'Biogesic');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/Biogesic', 'Searched for Biogesic');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'biogesic');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/biogesic', 'Searched with all lower case ');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'ItemNotFound');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/ItemNotFound', 'Searched for ItemNotFound');
    assert.equal(find('button:contains(Delete)').length, 0, 'There is no search result');
  });
});

const startAndEndDateReportTypes = [
  'Days Supply Left In Stock',
  'Detailed Adjustment',
  'Detailed Purchase',
  'Detailed Stock Usage',
  'Detailed Stock Transfer',
  'Detailed Expenses',
  'Expiration Date',
  'Summary Expenses',
  'Summary Purchase',
  'Summary Stock Usage',
  'Summary Stock Transfer',
  'Finance Summary'
];

const singleDateReportTypes = [
  'Inventory By Location',
  'Inventory Valuation'
];

startAndEndDateReportTypes.forEach((reportName) => {
  testSimpleReportForm(reportName);
  testReportWithEmptyEndDate(reportName);
  testReportWithEmptyEndDateBeforeStartDate(reportName);
});

singleDateReportTypes.forEach((reportName) => {
  testSingleDateReportForm(reportName);
});

function testSimpleReportForm(reportName) {
  test(`${reportName} report can be generated`, function(assert) {
    return runWithPouchDump('default', async function() {
      await authenticateUser();
      await visit('/inventory/reports');
      assert.equal(currentURL(), '/inventory/reports');

      let startDate = moment('2015-10-01');
      let endDate = moment('2015-10-31');
      await selectDate('.test-start-date input', startDate.toDate());
      await selectDate('.test-end-date input', endDate.toDate());
      await select('#report-type', `${reportName}`);
      await click('button:contains(Generate Report)');
      await waitToAppear('.panel-title');
      let reportTitle = `${reportName} Report ${startDate.format('l')} - ${endDate.format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}

async function generateReport(reportName, startDate, endDate) {
  await authenticateUser();
  await visit('/inventory/reports');

  if (startDate) {
    await selectDate('.test-start-date input', moment(startDate).toDate());
  }

  if (endDate) {
    await selectDate('.test-end-date input', moment(endDate).toDate());
  }

  await select('#report-type', `${reportName}`);
  await click('button:contains(Generate Report)');
}

function testReportWithEmptyEndDateBeforeStartDate(reportName) {
  test('${reportName} report with end date before start date should display an error', (assert) => {
    return runWithPouchDump('default', async function() {
      let endDate = '12/10/2016';
      let startDate = '12/11/2016';
      await generateReport(reportName, startDate, endDate);
      await waitToAppear('.modal-dialog');
      assert.dom('.modal-title').hasText('Error Generating Report', 'Error Generating Report');
      assert.dom('.modal-body').hasText('Please enter an end date after the start date.');
    });
  });
}

function testReportWithEmptyEndDate(reportName) {
  test(`${reportName} report can be generated with empty end date`, function(assert) {
    return runWithPouchDump('default', async function() {

      let startDate = '12/11/2016';
      let endDate = new Date();
      await generateReport(reportName, startDate, null);
      await waitToAppear('.panel-title');
      assert.equal(currentURL(), '/inventory/reports');
      let reportTitle = `${reportName} Report ${moment(startDate).format('l')} - ${moment(endDate).format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}

function testSingleDateReportForm(reportName) {
  test(`${reportName} report can be generated`, function(assert) {
    return runWithPouchDump('default', async function() {
      let startDate = new Date();
      await generateReport(reportName, null, null);
      await waitToAppear('.panel-title');
      assert.equal(currentURL(), '/inventory/reports');
      let reportTitle = `${reportName} Report ${moment(startDate).format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}
<commit_msg>fixes an issue where the test title was not printing the report name<commit_after>import moment from 'moment';
import { test } from 'qunit';
import moduleForAcceptance from 'hospitalrun/tests/helpers/module-for-acceptance';
import runWithPouchDump from 'hospitalrun/tests/helpers/run-with-pouch-dump';
import select from 'hospitalrun/tests/helpers/select';
import selectDate from 'hospitalrun/tests/helpers/select-date';
import typeAheadFillIn from 'hospitalrun/tests/helpers/typeahead-fillin';
import { waitToAppear } from 'hospitalrun/tests/helpers/wait-to-appear';
import { authenticateUser } from 'hospitalrun/tests/helpers/authenticate-user';

moduleForAcceptance('Acceptance | inventory');

test('visiting /inventory', function(assert) {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory');
    findWithAssert('button:contains(new request)');
    findWithAssert('button:contains(+ Inventory Received)');
    findWithAssert('p:contains(No requests found. )');
    findWithAssert('a:contains(Create a new request?)');
  });
});

test('Adding a new inventory item', (assert) => {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory/edit/new');
    assert.equal(currentURL(), '/inventory/edit/new');

    await fillIn('.test-inv-name input', 'Biogesic');
    await select('.test-inv-rank', 'B');
    await fillIn('textarea', 'Biogesic nga medisina');
    await select('.test-inv-type', 'Medication');
    await fillIn('.test-inv-cross input', '2600');
    await fillIn('.test-inv-reorder input', '100');
    await fillIn('.test-inv-price input', '5');
    await select('.test-inv-dist-unit', 'tablet');
    await fillIn('.test-inv-quantity input', '1000');
    await fillIn('.test-inv-cost input', '4000');
    await select('.test-inv-unit', 'tablet');
    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Inventory Item Saved', 'Inventory Item was saved successfully');

    await click('button:contains(Ok)');
    findWithAssert('button:contains(Add Purchase)');
    findWithAssert('button:contains(Update)');
    findWithAssert('button:contains(Return)');

    await click('button:contains(Add Purchase)');
    await waitToAppear('.modal-dialog');
    await fillIn('.test-inv-quantity div div input', 18);
    await fillIn('.test-inv-cost div input', 2);
    await fillIn('.test-vendor div span input:eq(1)', 'fakeVendor');
    await click('.modal-footer .btn-primary');
    assert.dom('div.alert.alert-danger.alert-dismissible').doesNotExist('Quantity error does not appear');
    assert.dom($('.test-location-quantity')[0]).hasText('1018', 'Location quantity is correct after new purchase');
    assert.dom('.test-inv-quantity p').hasText('1018', 'Item total quantity is correct after new purchase');

    await click('button:contains(Return)');
    assert.equal(currentURL(), '/inventory/listing');
    assert.dom('tr').exists({ count: 2 }, 'One item is listed');
  });
});

test('Items with negative quantites should not be saved', (assert) => {
  return runWithPouchDump('default', async function() {
    await authenticateUser();
    await visit('/inventory/edit/new');
    assert.equal(currentURL(), '/inventory/edit/new');

    await fillIn('.test-inv-name input', 'Biogesic');
    await select('.test-inv-rank', 'B');
    await fillIn('textarea', 'Biogesic nga medisina');
    await select('.test-inv-type', 'Medication');
    await fillIn('.test-inv-cross input', '2600');
    await fillIn('.test-inv-reorder input', '100');
    await fillIn('.test-inv-price input', '5');
    await select('.test-inv-dist-unit', 'tablet');
    await fillIn('.test-inv-quantity input', '-1000');
    await fillIn('.test-inv-cost input', '4000');
    await select('.test-inv-unit', 'tablet');
    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');

    assert.dom('.modal-title').hasText(
      'Warning!!!!',
      'Inventory Item with negative quantity should not be saved.'
    );

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory/edit/new');
    findWithAssert('button:contains(Add)');
    findWithAssert('button:contains(Cancel)');
    assert.dom('.test-inv-quantity .help-block').hasText(
      'not a valid number',
      'Error message should be present for invalid quantities'
    );
  });
});

test('Visiting /inventory/barcode', (assert) => {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/listing');
    assert.equal(currentURL(), '/inventory/listing');

    await click('a:contains(Barcode)');
    assert.equal(currentURL(), '/inventory/barcode/igbmk5zf_is');
    findWithAssert('.panel-body img[src^="data:image"]');
  });
});

test('Deleting the last inventory item', (assert) => {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/listing');
    assert.equal(currentURL(), '/inventory/listing');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Item', 'Deleting confirmation.');

    await click('.modal-content button:contains(Delete)');
    await waitToAppear('.panel-body .alert-info');
    assert.equal(currentURL(), '/inventory/listing');
    findWithAssert('a:contains(Create a new record?)');
  });
});

test('Creating a new inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/request/new');
    assert.equal(currentURL(), '/inventory/request/new');

    await typeAheadFillIn('.test-inv-item', 'Biogesic - m00001 (1000 available)');
    await fillIn('.test-inv-quantity input', 500);
    await typeAheadFillIn('.test-delivery-location', 'Harare');
    await typeAheadFillIn('.test-delivery-aisle', 'C100');
    await typeAheadFillIn('.test-bill-to', 'Accounts Dept');
    await click('button:contains(Add)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Request Updated', 'New request has been saved');

    await click('button:contains(Ok)');
    findWithAssert('button:contains(Fulfill)');
    findWithAssert('button:contains(Cancel)');

    await click('button:contains(Cancel)');
    assert.equal(currentURL(), '/inventory');
    assert.dom('tr').exists({ count: 3 }, 'Two requests are now displayed');
  });
});

test('Fulfilling an inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory');
    let tableRows = find('tr').length;
    assert.equal(tableRows, 2, 'One request not fulfilled');

    await click('button:contains(Fulfill)');
    findWithAssert('button:contains(Fulfill)');
    findWithAssert('button:contains(Cancel)');

    await waitToAppear('.inventory-location option:contains(No Location)');
    await click('button:contains(Fulfill)');
    await waitToAppear('.modal-dialog');

    let modalTitle = find('.modal-title');
    assert.equal(modalTitle.text(), 'Request Fulfilled', 'Inventory request has been fulfilled');

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory');
  });
});

test('Deleting an inventory request', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');
    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one request');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Item', 'Deleting confirmation');

    await click('.modal-content button:contains(Delete)');
    await waitToAppear('.panel-body .alert-info');
    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 0, 'Request was deleted');
  });
});

test('User with add_inventory_request and without fulfill_inventory rights should not be able to delete others\' requests', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser({
      name: 'nurse.mgr',
      roles: ['Nurse Manager', 'user'],
      role: 'Nurse Manager'
    });
    await visit('/inventory');

    assert.equal(currentURL(), '/inventory', 'Navigated to /inventory');
    assert.equal(find('button:contains(Delete)').length, 0, 'User doesn\'t see Delete button');
  });
});

test('Receiving inventory', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory/batch/new');
    assert.equal(currentURL(), '/inventory/batch/new');

    await typeAheadFillIn('.test-vendor', 'Alpha Pharmacy');
    await fillIn('.test-invoice-number input', 'P2345');
    await typeAheadFillIn('.test-inv-item', 'Biogesic - m00001');
    await fillIn('.test-inv-quantity input', 500);
    await fillIn('.test-inv-cost input', '2000');
    await waitToAppear('.inventory-distribution-unit');
    await click('button:contains(Save)');
    await waitToAppear('.modal-title');

    let modalTitle = find('.modal-title');
    assert.equal(modalTitle.text(), 'Inventory Purchases Saved', 'Inventory has been received');

    await click('button:contains(Ok)');
    assert.equal(currentURL(), '/inventory/listing');
  });
});

test('Searching inventory', function(assert) {
  return runWithPouchDump('inventory', async function() {
    await authenticateUser();
    await visit('/inventory');

    await fillIn('[role="search"] div input', 'Biogesic');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/Biogesic', 'Searched for Biogesic');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'biogesic');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/biogesic', 'Searched with all lower case ');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'ItemNotFound');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/inventory/search/ItemNotFound', 'Searched for ItemNotFound');
    assert.equal(find('button:contains(Delete)').length, 0, 'There is no search result');
  });
});

const startAndEndDateReportTypes = [
  'Days Supply Left In Stock',
  'Detailed Adjustment',
  'Detailed Purchase',
  'Detailed Stock Usage',
  'Detailed Stock Transfer',
  'Detailed Expenses',
  'Expiration Date',
  'Summary Expenses',
  'Summary Purchase',
  'Summary Stock Usage',
  'Summary Stock Transfer',
  'Finance Summary'
];

const singleDateReportTypes = [
  'Inventory By Location',
  'Inventory Valuation'
];

startAndEndDateReportTypes.forEach((reportName) => {
  testSimpleReportForm(reportName);
  testReportWithEmptyEndDate(reportName);
  testReportWithEmptyEndDateBeforeStartDate(reportName);
});

singleDateReportTypes.forEach((reportName) => {
  testSingleDateReportForm(reportName);
});

function testSimpleReportForm(reportName) {
  test(`${reportName} report can be generated`, function(assert) {
    return runWithPouchDump('default', async function() {
      await authenticateUser();
      await visit('/inventory/reports');
      assert.equal(currentURL(), '/inventory/reports');

      let startDate = moment('2015-10-01');
      let endDate = moment('2015-10-31');
      await selectDate('.test-start-date input', startDate.toDate());
      await selectDate('.test-end-date input', endDate.toDate());
      await select('#report-type', `${reportName}`);
      await click('button:contains(Generate Report)');
      await waitToAppear('.panel-title');
      let reportTitle = `${reportName} Report ${startDate.format('l')} - ${endDate.format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}

async function generateReport(reportName, startDate, endDate) {
  await authenticateUser();
  await visit('/inventory/reports');

  if (startDate) {
    await selectDate('.test-start-date input', moment(startDate).toDate());
  }

  if (endDate) {
    await selectDate('.test-end-date input', moment(endDate).toDate());
  }

  await select('#report-type', `${reportName}`);
  await click('button:contains(Generate Report)');
}

function testReportWithEmptyEndDateBeforeStartDate(reportName) {
  test(`${reportName} report with end date before start date should display an error`, (assert) => {
    return runWithPouchDump('default', async function() {
      let endDate = '12/10/2016';
      let startDate = '12/11/2016';
      await generateReport(reportName, startDate, endDate);
      await waitToAppear('.modal-dialog');
      assert.dom('.modal-title').hasText('Error Generating Report', 'Error Generating Report');
      assert.dom('.modal-body').hasText('Please enter an end date after the start date.');
    });
  });
}

function testReportWithEmptyEndDate(reportName) {
  test(`${reportName} report can be generated with empty end date`, function(assert) {
    return runWithPouchDump('default', async function() {

      let startDate = '12/11/2016';
      let endDate = new Date();
      await generateReport(reportName, startDate, null);
      await waitToAppear('.panel-title');
      assert.equal(currentURL(), '/inventory/reports');
      let reportTitle = `${reportName} Report ${moment(startDate).format('l')} - ${moment(endDate).format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}

function testSingleDateReportForm(reportName) {
  test(`${reportName} report can be generated`, function(assert) {
    return runWithPouchDump('default', async function() {
      let startDate = new Date();
      await generateReport(reportName, null, null);
      await waitToAppear('.panel-title');
      assert.equal(currentURL(), '/inventory/reports');
      let reportTitle = `${reportName} Report ${moment(startDate).format('l')}`;
      assert.dom('.panel-title').hasText(reportTitle, `${reportName} Report generated`);
      let exportLink = findWithAssert('a:contains(Export Report)');
      assert.equal($(exportLink).attr('download'), `${reportTitle}.csv`);
    });
  });
}
<|endoftext|>


<commit_before>/* global ranTransition, noTransitionsYet */
import Ember from 'ember';
import startApp from '../helpers/start-app';
import { injectTransitionSpies,
         classFound,
         clickWithoutWaiting } from '../helpers/integration';

var App;

module('Acceptance: Scenarios', {
  setup: function() {
    App = startApp();
    injectTransitionSpies(App);
  },
  teardown: function() {
    Ember.run(App, 'destroy');
  }
});

test('nested liquid-outlets wait for their ancestors to animate', function() {
  visit('/scenarios/nested-outlets/middle/inner');
  andThen(function(){
    visit('/scenarios/nested-outlets/middle2');
    Ember.run.later(function(){
      equal(find('#inner-index').length, 1, "inner view exists during animation");
    }, 30);
  });
});

test('modal with remapped parameters receives them', function() {
  expect(2);
  visit('/scenarios/remapped-modal');
  andThen(function(){
    click('a:contains(Go)');
  });
  andThen(function(){
    console.log("finding with assert");
    findWithAssert('.lf-dialog:contains(Hi Tomster)');
    ok(true);
    click('button:contains(Thanks)');
  });
  andThen(function(){
    equal(find('.lf-dialog').length, 0, "expected dialog to be dismissed");
  });
});
<commit_msg>failing unit test for #204<commit_after>/* global ranTransition, noTransitionsYet */
import Ember from 'ember';
import startApp from '../helpers/start-app';
import { injectTransitionSpies,
         classFound,
         clickWithoutWaiting } from '../helpers/integration';

var App;

module('Acceptance: Scenarios', {
  setup: function() {
    App = startApp();
    injectTransitionSpies(App);
  },
  teardown: function() {
    Ember.run(App, 'destroy');
  }
});

test('nested liquid-outlets wait for their ancestors to animate', function() {
  visit('/scenarios/nested-outlets/middle/inner');
  andThen(function(){
    visit('/scenarios/nested-outlets/middle2');
    Ember.run.later(function(){
      equal(find('#inner-index').length, 1, "inner view exists during animation");
    }, 30);
  });
});

test('inner nested liquid-outlets can animate', function() {
  visit('/scenarios/nested-outlets/middle/inner');
  visit('/scenarios/nested-outlets/middle');
  andThen(function(){
    ranTransition('fade');
  });
});

test('modal with remapped parameters receives them', function() {
  expect(2);
  visit('/scenarios/remapped-modal');
  andThen(function(){
    click('a:contains(Go)');
  });
  andThen(function(){
    console.log("finding with assert");
    findWithAssert('.lf-dialog:contains(Hi Tomster)');
    ok(true);
    click('button:contains(Thanks)');
  });
  andThen(function(){
    equal(find('.lf-dialog').length, 0, "expected dialog to be dismissed");
  });
});
<|endoftext|>


<commit_before>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles.js');

describe('Component.Base', function() {

    it('has exactly one related entity', function() {
        const entity = new RG.Entity();
        const entity2 = new RG.Entity();
        const comp = new RG.Component.Base('Base');

        expect(comp.getType()).to.equal('Base');

        comp.setEntity(entity);
        expect(comp.getEntity().getID()).to.equal(entity.getID());

        // Try to override the entity
        RG.suppressErrorMessages = true;
        comp.setEntity(entity2);
        expect(comp.getEntity().getID()).to.equal(entity.getID());
        RG.suppressErrorMessages = false;

        comp.setEntity(null);
        expect(comp.getEntity()).to.be.null;
    });

    it('can be copied, cloned, compared', function() {
        const comp = new RG.Component.Base('Base');
        const compClone = comp.clone();
        expect(comp.equals(compClone)).to.be.true;
        expect(compClone.equals(comp)).to.be.true;

        const compCopy = new RG.Component.Base('XXX');
        compCopy.copy(comp);
        expect(comp.equals(compCopy)).to.be.true;

        expect(comp.toString()).to.match(/Base/);

    });

    it('has onAdd/Remove callback mechanism', function() {
        const comp = new RG.Component.Base('Base');
        const entity = new RG.Entity();

        let calledAdd = false;
        const callbackAdd = function() {calledAdd = true;};

        let calledRemove = false;
        const callbackRemove = function() {calledRemove = true;};

        let calledIllegal = false;
        const callbackIllegal = function() {calledIllegal = true;};

        comp.addCallback('onAdd', callbackAdd);
        comp.addCallback('onRemove', callbackRemove);
        RG.suppressErrorMessages = true;
        comp.addCallback('onIllegal', callbackIllegal);
        RG.suppressErrorMessages = false;

        expect(calledIllegal).to.be.false;

        expect(calledAdd).to.be.false;
        entity.add('Base', comp);
        expect(calledAdd).to.be.true;

        expect(calledRemove).to.be.false;
        entity.remove('Base');
        expect(calledRemove).to.be.true;
        expect(calledIllegal).to.be.false;
    });
});
<commit_msg>Added test for Comp.Combat.<commit_after>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles.js');

describe('Component.Base', function() {

    it('has exactly one related entity', function() {
        const entity = new RG.Entity();
        const entity2 = new RG.Entity();
        const comp = new RG.Component.Base('Base');

        expect(comp.getType()).to.equal('Base');

        comp.setEntity(entity);
        expect(comp.getEntity().getID()).to.equal(entity.getID());

        // Try to override the entity
        RG.suppressErrorMessages = true;
        comp.setEntity(entity2);
        expect(comp.getEntity().getID()).to.equal(entity.getID());
        RG.suppressErrorMessages = false;

        comp.setEntity(null);
        expect(comp.getEntity()).to.be.null;
    });

    it('can be copied, cloned, compared', function() {
        const comp = new RG.Component.Base('Base');
        const compClone = comp.clone();
        expect(comp.equals(compClone)).to.be.true;
        expect(compClone.equals(comp)).to.be.true;

        const compCopy = new RG.Component.Base('XXX');
        compCopy.copy(comp);
        expect(comp.equals(compCopy)).to.be.true;

        expect(comp.toString()).to.match(/Base/);

    });

    it('has onAdd/Remove callback mechanism', function() {
        const comp = new RG.Component.Base('Base');
        const entity = new RG.Entity();

        let calledAdd = false;
        const callbackAdd = function() {calledAdd = true;};

        let calledRemove = false;
        const callbackRemove = function() {calledRemove = true;};

        let calledIllegal = false;
        const callbackIllegal = function() {calledIllegal = true;};

        comp.addCallback('onAdd', callbackAdd);
        comp.addCallback('onRemove', callbackRemove);
        RG.suppressErrorMessages = true;
        comp.addCallback('onIllegal', callbackIllegal);
        RG.suppressErrorMessages = false;

        expect(calledIllegal).to.be.false;

        expect(calledAdd).to.be.false;
        entity.add('Base', comp);
        expect(calledAdd).to.be.true;

        expect(calledRemove).to.be.false;
        entity.remove('Base');
        expect(calledRemove).to.be.true;
        expect(calledIllegal).to.be.false;
    });
});

describe('Component.Combat', () => {
    it('contains damage dies for damage dealing', () => {
        const player = RG.FACT.createPlayer('Player', {});
        const combatComp = new RG.Component.Combat();
        player.add('Combat', combatComp);
        expect(player.get('Combat').getDamage() >= 1).to.equal(true);
        expect(player.get('Combat').getDamage() <= 4).to.equal(true);
    });
});
<|endoftext|>