Эх сурвалжийг харах

HUE-890 [jobsub] Unit test the frontend

Added jasmine tests for the Knockout viewModel
Added fixtures block to common_jasmine to test knockout's data-bind on elements
Enrico Berti 13 жил өмнө
parent
commit
cbba991e0c

+ 36 - 0
apps/jobsub/src/jobsub/templates/jasmine.mako

@@ -0,0 +1,36 @@
+<%inherit file="common_jasmine.mako"/>
+
+<%block name="specs">
+    <script src="/static/ext/js/moment.min.js"></script>
+    <script src="static/js/jobsub.ko.js"></script>
+    <script src="static/jasmine/jobsubSpec.js"></script>
+</%block>
+
+
+<%block name="fixtures">
+  <div style="display:none">
+    <button class="btn" data-bind="click: submitDesign, enable: selectedDesigns().length == 1 && selectedDesigns()[0].canSubmit"><i class="icon-play"></i> Submit</button>
+    <button class="btn" data-bind="click: editDesign, enable: selectedDesigns().length == 1 && selectedDesigns()[0].canSubmit"><i class="icon-pencil"></i> Edit</button>
+    <button class="btn" data-bind="click: deleteDesign, enable: selectedDesigns().length == 1 && selectedDesigns()[0].canDelete"><i class="icon-trash"></i> Delete</button>
+    <button class="btn" data-bind="click: cloneDesign, enable: selectedDesigns().length == 1"><i class="icon-share"></i> Clone</button>
+
+    <div id="selectAll" data-bind="click: selectAll, css: {hueCheckbox: true, 'icon-ok': allSelected}"></div>
+    <table id="designTable" class="table table-condensed datatables">
+      <tbody id="designs" data-bind="template: {name: 'designTemplate', foreach: designs}">
+
+      </tbody>
+    </table>
+    <script id="designTemplate" type="text/html">
+      <tr style="cursor: pointer">
+        <td class="center" data-bind="click: handleSelect" style="cursor: default">
+          <div data-bind="visible: name != '..', css: {hueCheckbox: name != '..', 'icon-ok': selected}"></div>
+        </td>
+        <td data-bind="click: $root.editDesign, text: owner"></td>
+        <td data-bind="click: $root.editDesign, text: name"></td>
+        <td data-bind="click: $root.editDesign, text: type"></td>
+        <td data-bind="click: $root.editDesign, text: description"></td>
+        <td data-bind="click: $root.editDesign, text: lastModified, attr: { 'data-sort-value': lastModifiedMillis }" style="white-space: nowrap;"></td>
+      </tr>
+    </script>
+  </div>
+</%block>

+ 3 - 0
apps/jobsub/src/jobsub/urls.py

@@ -36,4 +36,7 @@ urlpatterns = patterns(
 
   # Setup
   url(r'^setup/$', 'views.setup'),
+
+  # Jasmine
+  url(r'^jasmine', 'views.jasmine'),
 )

+ 2 - 0
apps/jobsub/src/jobsub/views.py

@@ -298,6 +298,8 @@ def setup(request):
     raise PopupException(_('The examples could not be installed.'), detail=e)
   return redirect(urlresolvers.reverse(list_designs))
 
+def jasmine(request):
+  return render('jasmine.mako', request, None)
 
 
 # See http://wiki.apache.org/hadoop/JobConfFile

+ 101 - 0
apps/jobsub/static/jasmine/jobsubSpec.js

@@ -0,0 +1,101 @@
+
+describe("JobSubModel", function(){
+  var viewModel;
+
+  function getSampleDesign(id, canSubmit, canDelete){
+    return {
+      "url_params":"/fake/params/url/"+id,
+      "description":"[Sample] Jasmine Job "+id,
+      "last_modified":1350993390 + id,
+      "can_delete":canDelete,
+      "owner":"jasmine",
+      "url_edit":"/fake/edit/url/"+id,
+      "url_submit":"/fake/submit/url/"+id,
+      "id":id,
+      "can_submit":canSubmit,
+      "name":"jasmine_job_"+id,
+      "url_clone":"/fake/clone/url/"+id,
+      "url_delete":"/fake/delete/url/"+id,
+      "type":"mapreduce"
+    }
+  }
+
+
+  var sampleDesigns = [
+    getSampleDesign(1, true, true),
+    getSampleDesign(2, false, true),
+    getSampleDesign(3, false, false)
+  ];
+
+  beforeEach(function(){
+    viewModel = new JobSubModel(sampleDesigns);
+    ko.applyBindings(viewModel);
+  });
+
+  it("should render the design table on applyBindings", function(){
+    expect($("#designs tr").length).toEqual(viewModel.designs().length);
+  });
+
+  describe("When clicking select all", function(){
+
+    it("should select first all designs and deselect them all", function(){
+      viewModel.selectAll();
+      expect(viewModel.selectedDesigns().length).toEqual(viewModel.designs().length);
+      viewModel.selectAll();
+      expect(viewModel.selectedDesigns().length).toEqual(0);
+    });
+
+    it("should add a css class to the 'Select All' checkbox", function(){
+      viewModel.selectAll();
+      expect($("#selectAll").hasClass("icon-ok")).toBeTruthy();
+    });
+
+    it("should disable the action buttons", function(){
+      viewModel.selectAll();
+      expect($(".btn:enabled").length).toEqual(0);
+    });
+
+  });
+
+  describe("When selecting a design", function(){
+
+    it("should return a selectedDesign", function(){
+      viewModel.designs()[0].selected(true);
+      expect(viewModel.selectedDesign().name).toEqual(viewModel.designs()[0].name);
+    });
+
+    it("should always enable the clone button", function(){
+      viewModel.designs()[0].selected(true);
+      expect($(".btn:enabled:contains('Clone')").length).toEqual(1);
+      viewModel.designs()[0].selected(false);
+      expect($(".btn:enabled:contains('Clone')").length).toEqual(0);
+      viewModel.designs()[1].selected(true);
+      expect($(".btn:enabled:contains('Clone')").length).toEqual(1);
+    });
+
+    it("should enable the submit button if canSubmit is true", function(){
+      viewModel.designs()[0].selected(true);
+      expect($(".btn:enabled:contains('Submit')").length).toEqual(1);
+      viewModel.designs()[0].selected(false);
+      viewModel.designs()[1].selected(true);
+      expect($(".btn:enabled:contains('Submit')").length).toEqual(0);
+    });
+
+    it("should enable the edit button if canSubmit is true", function(){
+      viewModel.designs()[0].selected(true);
+      expect($(".btn:enabled:contains('Edit')").length).toEqual(1);
+      viewModel.designs()[0].selected(false);
+      viewModel.designs()[1].selected(true);
+      expect($(".btn:enabled:contains('Edit')").length).toEqual(0);
+    });
+
+    it("should enable the delete button if canDelete is true", function(){
+      viewModel.designs()[1].selected(true);
+      expect($(".btn:enabled:contains('Delete')").length).toEqual(1);
+      viewModel.designs()[1].selected(false);
+      viewModel.designs()[2].selected(true);
+      expect($(".btn:enabled:contains('Delete')").length).toEqual(0);
+    });
+
+  });
+});

+ 1 - 0
desktop/core/src/desktop/templates/common_jasmine.mako

@@ -61,5 +61,6 @@
 </head>
 
 <body>
+    <%block name="fixtures"/>
 </body>
 </html>