Skip to content
This repository has been archived by the owner on Apr 5, 2018. It is now read-only.

Commit

Permalink
Feature/unit testing (#71)
Browse files Browse the repository at this point in the history
- Added unit tests by jasmine-karma and e2e test by protractor.
- Edited Selenium jar folder to point to grunt-protractor-runner instead of protractor. 
- **For local use**: inside the `e2e.config.js` file, add `'phantomjs.binary.path': 'node_modules/phantomjs-prebuilt/phantomjs/phantomjs-2.1.1-linux-x86_64/bin/phantomjs'` inside `capabilities`, make sure this changes will not be pushed into github --> to get rid of error `The path to the driver executable must be set by the phantomjs.binary.path capability/system property/PATH variable` but this does not happen in travis
- More details on writing e2e test, should look at the tutorial from protractor : http://www.protractortest.org/#/tutorial 
- Unit tests: 
   - workflowservice.js --> to test the service using $httpBackend
   - registerworkflow.js --> added more test to test the controller
- End to End tests: 
   - app.spec.js --> make sure it connects to the homepage
   - workflowDetails.js --> test editButton that should not exists in published workflow in "Workflows"
  • Loading branch information
Janice Patricia authored and denis-yuen committed Aug 2, 2016
1 parent a7414d7 commit 214f4a4
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 15 deletions.
4 changes: 2 additions & 2 deletions app/templates/workflowdetails.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ <h3 class="pull-right">
<div ng-show="editMode && showEditWorkflowPath">
<strong>Workflow Path</strong>:
{{workflowObj.workflow_path}}
<button type="sbutton"
<button type="sbutton" id="editButton"
class="btn btn-link pull-right"
ng-click="showEditWorkflowPath = false">
<span class="glyphicon glyphicon-edit"></span>Edit
Expand Down Expand Up @@ -215,7 +215,7 @@ <h3 class="pull-right">
<div ng-show="editMode && showEditDescriptorType">
<Strong>Descriptor Type</Strong>:
{{workflowObj.descriptorType | lowercase}}
<button type="sbutton"
<button type="sbutton" id="editButton"
class="btn btn-link pull-right"
style="padding: 3px 12px!important;"
ng-click="showEditDescriptorType = false">
Expand Down
2 changes: 1 addition & 1 deletion e2e.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports.config = {
// to the location of this config. If no other method of starting selenium
// is found, this will default to
// node_modules/protractor/selenium/selenium-server...
seleniumServerJar: './node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-2.53.1.jar',
seleniumServerJar: 'node_modules/grunt-protractor-runner/node_modules/protractor/selenium/selenium-server-standalone-2.52.0.jar',

// The port to start the selenium server on, or null if the server should
// find its own unused port.
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/app-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

/* https://github.com/angular/protractor/blob/master/docs/getting-started.md */

describe('my app', function() {
describe('dockstore homepage', function() {

beforeEach(function () {
browser.get('index.html');
});

it('should automatically redirect to / when location hash is empty', function() {
expect(browser.getLocationAbsUrl()).toMatch("/");
});
});
});
});
23 changes: 23 additions & 0 deletions test/e2e/workflowDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

'use strict';

/* https://github.com/angular/protractor/blob/master/docs/getting-started.md */

var page = function(){
this.button = element(by.id("editButton"));
};

describe('Dockstore Workflow Details', function() {
var Page = new page();

beforeEach(function () {
browser.ignoreSynchronization = true; //to avoid error angular is not found --> could be because of syncing problem
browser.get('workflows/DockstoreTestUser/hello-dockstore-workflow');
});

it('should not have Edit button', function() {
// edit button should only appear inside "My Workflows"
// unless logged in as the author, edit button should not be present in "Workflows"
expect(Page.button.isPresent()).toBe(false);
});
});
32 changes: 24 additions & 8 deletions test/spec/controllers/registerworkflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,34 @@ describe('Controller: RegisterWorkflowCtrl', function () {

// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {

scope = $rootScope.$new();

RegisterWorkflowCtrl = $controller('RegisterWorkflowCtrl', {
$scope: scope
// place here mocked dependencies
});
$scope: scope
// place here mocked dependencies
});
}));

it('should change the extension', function(){
expect(scope.changeExt('/foo.cwl','wdl')).toBe('/foo.wdl');
expect(scope.changeExt('/Dockstore.cwl','wdl')).toBe('/Dockstore.wdl');
});

describe('test setWorkflowEditError', function(){
it('should set error message and errordetails', function(){
scope.setWorkflowEditError("errorMessage","errorDetails");
expect(scope.workflowEditError.message).toBe("errorMessage");
expect(scope.workflowEditError.errorDetails).toBe("errorDetails");
});

it('should return null', function() {
scope.setWorkflowEditError("","");
expect(scope.workflowEditError).toBeNull();
});
});

it('should get workflow path', function(){
expect(scope.getWorkflowPath('/Dockstore.cwl','')).toBe('Dockstore.cwl');
});

// it('should attach a list of awesomeThings to the scope', function () {
// expect(RegisterWorkflowCtrl.awesomeThings.length).toBe(3);
// });
});
});
129 changes: 129 additions & 0 deletions test/spec/services/workflowservice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
'use strict';

describe('Service: WorkflowService', function () {

// load the service's module
beforeEach(module('dockstore.ui'));

// instantiate service
var WorkflowService, httpBackend;

beforeEach(inject(function (_WorkflowService_, $httpBackend) {
WorkflowService = _WorkflowService_;
httpBackend = $httpBackend;
}));

describe('mocking services: GET', function() {
// test taken from https://github.com/DockstoreTestUser/hello-dockstore-workflow/tree/testBoth

it('should mock getDescriptorFile', function(){
// mock getDescriptorFile
httpBackend.whenGET("http://localhost:8080/workflows/1114/cwl?tag=testBoth").respond({
"id": 1533,
"type": "DOCKSTORE_CWL",
"content": "#\n# This is a two-step workflow which uses \"revtool\" and \"sorttool\" defined above.\n#\nclass: Workflow\ndescription: \"A demonstration of a CWL workflow. This reverses the lines in a document and then sorts those lines.\"\ncwlVersion: cwl:draft-3\n\n# Requirements & hints specify prerequisites and extensions to the workflow.\n# In this example, DockerRequirement specifies a default Docker container\n# in which the command line tools will execute.\nhints:\n - class: DockerRequirement\n dockerPull: debian:8\n\n\n# The inputs array defines the structure of the input object that describes\n# the inputs to the workflow.\n#\n# The \"reverse_sort\" input parameter demonstrates the \"default\" field. If the\n# field \"reverse_sort\" is not provided in the input object, the default value will\n# be used.\ninputs:\n - id: input\n type: File\n description: \"The input file to be processed.\"\n - id: reverse_sort\n type: boolean\n default: true\n description: \"If true, reverse (decending) sort\"\n\n# The \"outputs\" array defines the structure of the output object that describes\n# the outputs of the workflow.\n#\n# Each output field must be connected to the output of one of the workflow\n# steps using the \"connect\" field. Here, the parameter \"#output\" of the\n# workflow comes from the \"#sorted\" output of the \"sort\" step.\noutputs:\n - id: output\n type: File\n source: \"#sorted/output\"\n description: \"The output with the lines reversed and sorted.\"\n\n# The \"steps\" array lists the executable steps that make up the workflow.\n# The tool to execute each step is listed in the \"run\" field.\n#\n# In the first step, the \"inputs\" field of the step connects the upstream\n# parameter \"#input\" of the workflow to the input parameter of the tool\n# \"revtool.cwl#input\"\n#\n# In the second step, the \"inputs\" field of the step connects the output\n# parameter \"#reversed\" from the first step to the input parameter of the\n# tool \"sorttool.cwl#input\".\nsteps:\n - id: rev\n inputs:\n - { id: input, source: \"#input\" }\n outputs:\n - { id: output }\n run: revtool.cwl\n\n\n - id: sorted\n inputs:\n - { id: input, source: \"#rev/output\" }\n - { id: reverse, source: \"#reverse_sort\" }\n outputs:\n - { id: output }\n run: sorttool.cwl\n",
"path": "/Dockstore.cwl"
});

WorkflowService.getDescriptorFile(1114,'testBoth','cwl')
.then(function(response){
expect(response).toBe("#\n# This is a two-step workflow which uses \"revtool\" and \"sorttool\" defined above.\n#\nclass: Workflow\ndescription: \"A demonstration of a CWL workflow. This reverses the lines in a document and then sorts those lines.\"\ncwlVersion: cwl:draft-3\n\n# Requirements & hints specify prerequisites and extensions to the workflow.\n# In this example, DockerRequirement specifies a default Docker container\n# in which the command line tools will execute.\nhints:\n - class: DockerRequirement\n dockerPull: debian:8\n\n\n# The inputs array defines the structure of the input object that describes\n# the inputs to the workflow.\n#\n# The \"reverse_sort\" input parameter demonstrates the \"default\" field. If the\n# field \"reverse_sort\" is not provided in the input object, the default value will\n# be used.\ninputs:\n - id: input\n type: File\n description: \"The input file to be processed.\"\n - id: reverse_sort\n type: boolean\n default: true\n description: \"If true, reverse (decending) sort\"\n\n# The \"outputs\" array defines the structure of the output object that describes\n# the outputs of the workflow.\n#\n# Each output field must be connected to the output of one of the workflow\n# steps using the \"connect\" field. Here, the parameter \"#output\" of the\n# workflow comes from the \"#sorted\" output of the \"sort\" step.\noutputs:\n - id: output\n type: File\n source: \"#sorted/output\"\n description: \"The output with the lines reversed and sorted.\"\n\n# The \"steps\" array lists the executable steps that make up the workflow.\n# The tool to execute each step is listed in the \"run\" field.\n#\n# In the first step, the \"inputs\" field of the step connects the upstream\n# parameter \"#input\" of the workflow to the input parameter of the tool\n# \"revtool.cwl#input\"\n#\n# In the second step, the \"inputs\" field of the step connects the output\n# parameter \"#reversed\" from the first step to the input parameter of the\n# tool \"sorttool.cwl#input\".\nsteps:\n - id: rev\n inputs:\n - { id: input, source: \"#input\" }\n outputs:\n - { id: output }\n run: revtool.cwl\n\n\n - id: sorted\n inputs:\n - { id: input, source: \"#rev/output\" }\n - { id: reverse, source: \"#reverse_sort\" }\n outputs:\n - { id: output }\n run: sorttool.cwl\n");
});
httpBackend.flush();
});

it('should mock getWorkflowDAG', function(){
// mock getWorkflowDAG
httpBackend.whenGET("http://localhost:8080/workflows/1114/dag/1151").respond({
"nodes": [
{
"data": {
"name": "rev",
"id": "0",
"tool": "https://hub.docker.com/_/ubuntu"
}
},
{
"data": {
"name": "sorted",
"id": "1",
"tool": "https://hub.docker.com/_/ubuntu"
}
}
],
"edges": [
{
"data": {
"source": "0",
"target": "1"
}
}
]
});

WorkflowService.getWorkflowDag(1114,1151)
.then(function(response){
expect(response.nodes.length).toBe(2);
expect(response.edges.length).toBe(1);
expect(response.nodes[0].data.name).toBe('rev');
expect(response.nodes[1].data.name).toBe('sorted');
expect(response.edges[0].data.source).toBe('0');
expect(response.edges[0].data.target).toBe('1');
});
httpBackend.flush();
});

it('should mock getTableToolContent', function() {
// mock getTableToolContent
httpBackend.whenGET("http://localhost:8080/workflows/1114/tools/1151").respond([
{
"id": "rev",
"file": "revtool.cwl",
"docker": "debian:8",
"link": "https://hub.docker.com/_/debian"
},
{
"id": "sorted",
"file": "sorttool.cwl",
"docker": "debian:8",
"link": "https://hub.docker.com/_/debian"
}
]);

WorkflowService.getTableToolContent(1114, 1151)
.then(function(response){
expect(response.length).toBe(2);
expect(response[0].id).toBe('rev');
expect(response[1].id).toBe('sorted');
});
httpBackend.flush();
});
});

describe('mocking services: PUT', function() {
//mock setDefaultWorkflowPath
it('should mock setDefaultWorkflowPath', function() {
httpBackend.whenPUT("http://localhost:8080/workflows/1114").respond({
//NOTE: this is just part of the real content. For complete full content, check the webservice
"id": 1114,
"author": null,
"description": null,
"labels": [],
"gitUrl": "[email protected]:DockstoreTestUser/hello-dockstore-workflow.git",
"mode": "FULL",
"workflowName": null,
"path": "DockstoreTestUser/hello-dockstore-workflow",
"descriptorType": "cwl",
"workflow_path": "/test/Dockstore.cwl"
});

WorkflowService.setDefaultWorkflowPath(1114,"/test/Dockstore.cwl",null,"cwl",
"DockstoreTestUser/hello-dockstore-workflow","[email protected]:DockstoreTestUser/hello-dockstore-workflow.git")
.then(function(response){
expect(response.workflow_path).toBe('/test/Dockstore.cwl');
});
httpBackend.flush();
});
});

});

0 comments on commit 214f4a4

Please sign in to comment.