--- a
+++ b/qiita_pet/test/test_software.py
@@ -0,0 +1,254 @@
+# -----------------------------------------------------------------------------
+# Copyright (c) 2014--, The Qiita Development Team.
+#
+# Distributed under the terms of the BSD 3-clause License.
+#
+# The full license is in the file LICENSE, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from unittest import main
+from qiita_pet.test.tornado_test_base import TestHandlerBase
+
+from mock import Mock
+from copy import deepcopy
+
+from qiita_db.sql_connection import TRN
+from qiita_db.user import User
+from qiita_db.software import DefaultWorkflow
+from qiita_db.sql_connection import perform_as_transaction
+from qiita_pet.handlers.base_handlers import BaseHandler
+from qiita_pet.handlers.software import _retrive_workflows
+
+
+class TestSoftware(TestHandlerBase):
+    def test_get(self):
+        response = self.get('/software/')
+        self.assertEqual(response.code, 200)
+        body = response.body.decode('ascii')
+        self.assertNotEqual(body, "")
+        # checking that this software is not displayed
+        self.assertNotIn('Target Gene', body)
+
+        BaseHandler.get_current_user = Mock(return_value=User("admin@foo.bar"))
+        response = self.get('/software/')
+        self.assertEqual(response.code, 200)
+        body = response.body.decode('ascii')
+        self.assertNotEqual(body, "")
+        # checking that this software is displayed
+        self.assertIn('Target Gene', body)
+
+
+class TestWorkflowsHandler(TestHandlerBase):
+    def test_get(self):
+        DefaultWorkflow(2).active = False
+        response = self.get('/workflows/')
+        self.assertEqual(response.code, 200)
+        body = response.body.decode('ascii')
+        self.assertNotEqual(body, "")
+        # checking that this software is not displayed
+        self.assertNotIn('FASTA upstream workflow', body)
+
+        BaseHandler.get_current_user = Mock(return_value=User("admin@foo.bar"))
+        response = self.get('/workflows/')
+        self.assertEqual(response.code, 200)
+        body = response.body.decode('ascii')
+        self.assertNotEqual(body, "")
+        # checking that this software is displayed
+        self.assertIn('FASTA upstream workflow', body)
+        DefaultWorkflow(2).active = True
+
+    def test_retrive_workflows(self):
+        # we should see all 3 workflows
+        DefaultWorkflow(2).active = False
+        exp = deepcopy(WORKFLOWS)
+        self.assertCountEqual(_retrive_workflows(False), exp)
+
+        # validating that the params_name is not being used
+        self.assertNotIn(
+            'Split libraries | Defaults with Golay 12 barcodes',
+            [x[2] for x in _retrive_workflows(False)[1]['nodes']])
+        # now it should be there
+        with TRN:
+            # Hard-coded values; 19 -> barcode_type
+            sql = """UPDATE qiita.command_parameter
+                     SET name_order = 0
+                     WHERE command_parameter_id = 19"""
+            TRN.add(sql)
+            TRN.execute()
+        self.assertIn(
+            'Split libraries | Defaults with Golay 12 barcodes',
+            [x[2] for x in _retrive_workflows(False)[1]['nodes']])
+        # and gone again
+        with TRN:
+            sql = """UPDATE qiita.command_parameter
+                     SET name_order = NULL
+                     WHERE command_parameter_id = 19"""
+            TRN.add(sql)
+            TRN.execute()
+        self.assertNotIn(
+            'Split libraries | Defaults with Golay 12 barcodes',
+            [x[2] for x in _retrive_workflows(False)[1]['nodes']])
+
+        # we should not see the middle one
+        del exp[1]
+        self.assertCountEqual(_retrive_workflows(True), exp)
+
+        # let's create a couple of more complex scenarios so we touch all code
+        # by adding multiple paths, that should connect and get separate
+        # -- adds a new path that should be kept separate all the way; this is
+        #    to emulate what happens with different trimming (different
+        #    default parameter) and deblur (same for each of the previous
+        #    steps)
+        sql = """
+            INSERT INTO qiita.default_workflow_node (
+                default_workflow_id, default_parameter_set_id)
+            VALUES (1, 2), (1, 10);
+            INSERT INTO qiita.default_workflow_edge (
+                parent_id, child_id)
+            VALUES (7, 8);
+            INSERT INTO qiita.default_workflow_edge_connections (
+                default_workflow_edge_id, parent_output_id, child_input_id)
+            VALUES (4, 1, 3)"""
+        perform_as_transaction(sql)
+        # -- adds a new path that should be kept together and then separate;
+        #    this is to simulate what happens with MTX/WGS processing, one
+        #    single QC step (together) and 2 separete profilers
+        sql = """
+            INSERT INTO qiita.default_parameter_set (
+                command_id, parameter_set_name, parameter_set)
+            VALUES (3, '100%',
+                    ('{"reference":1,"sortmerna_e_value":1,'
+                     || '"sortmerna_max_pos":'
+                     || '10000,"similarity":1.0,"sortmerna_coverage":1.00,'
+                     || '"threads":1}')::json);
+            INSERT INTO qiita.default_workflow_node (
+                default_workflow_id, default_parameter_set_id)
+            VALUES (2, 17);
+            INSERT INTO qiita.default_workflow_edge (
+                parent_id, child_id)
+            VALUES (3, 9);
+            INSERT INTO qiita.default_workflow_edge_connections (
+                default_workflow_edge_id, parent_output_id, child_input_id)
+            VALUES (5, 1, 3)"""
+        perform_as_transaction(sql)
+
+        # adding new expected values
+        exp = deepcopy(WORKFLOWS)
+        obs = _retrive_workflows(False)
+        exp[0]['nodes'].extend([
+            ['params_7', 1, 'Split libraries FASTQ', 'Defaults with reverse '
+             'complement mapping file barcodes', {
+                'max_bad_run_length': '3',
+                'min_per_read_length_fraction': '0.75',
+                'sequence_max_n': '0', 'rev_comp_barcode': 'False',
+                'rev_comp_mapping_barcodes': 'True', 'rev_comp': 'False',
+                'phred_quality_threshold': '3', 'barcode_type': 'golay_12',
+                'max_barcode_errors': '1.5', 'phred_offset': 'auto'}],
+            ['input_params_7_FASTQ | per_sample_FASTQ', 1,
+             'FASTQ | per_sample_FASTQ'],
+            ['output_params_7_demultiplexed | Demultiplexed', 1,
+             'demultiplexed | Demultiplexed'],
+            ['params_8', 3, 'Pick closed-reference OTUs', 'Defaults', {
+                'reference': '1', 'sortmerna_e_value': '1',
+                'sortmerna_max_pos': '10000', 'similarity': '0.97',
+                'sortmerna_coverage': '0.97', 'threads': '1'}],
+            ['output_params_8_OTU table | BIOM', 3, 'OTU table | BIOM']])
+        exp[0]['edges'].extend([
+            ['input_params_7_FASTQ | per_sample_FASTQ', 'params_7'],
+            ['params_7', 'output_params_7_demultiplexed | Demultiplexed'],
+            ['output_params_7_demultiplexed | Demultiplexed', 'params_8'],
+            ['params_8', 'output_params_8_OTU table | BIOM']])
+        exp[1]['nodes'].extend([
+            ['params_9', 3, 'Pick closed-reference OTUs', '100%', {
+                'reference': '1', 'sortmerna_e_value': '1',
+                'sortmerna_max_pos': '10000', 'similarity': '1.0',
+                'sortmerna_coverage': '1.0', 'threads': '1'}],
+            ['output_params_9_OTU table | BIOM', 3, 'OTU table | BIOM']])
+        exp[1]['edges'].extend([
+            ['output_params_3_demultiplexed | Demultiplexed', 'params_9'],
+            ['params_9', 'output_params_9_OTU table | BIOM']
+        ])
+        self.assertCountEqual(obs, exp)
+
+
+WORKFLOWS = [
+    {'name': 'FASTQ upstream workflow', 'id': 1, 'data_types': ['16S', '18S'],
+     'description': 'This accepts html <a href="https://qiita.ucsd.edu">Qiita!'
+                    '</a><br/><br/><b>BYE!</b>',
+     'active': True, 'parameters_sample': {}, 'parameters_prep': {},
+     'nodes': [
+        ['params_1', 1, 'Split libraries FASTQ', 'Defaults', {
+            'max_bad_run_length': '3', 'min_per_read_length_fraction': '0.75',
+            'sequence_max_n': '0', 'rev_comp_barcode': 'False',
+            'rev_comp_mapping_barcodes': 'False', 'rev_comp': 'False',
+            'phred_quality_threshold': '3', 'barcode_type': 'golay_12',
+            'max_barcode_errors': '1.5', 'phred_offset': 'auto'}],
+        ['input_params_1_FASTQ', 1,
+         'FASTQ'],
+        ['output_params_1_demultiplexed | Demultiplexed', 1,
+         'demultiplexed | Demultiplexed'],
+        ['params_2', 3, 'Pick closed-reference OTUs', 'Defaults', {
+            'reference': '1', 'sortmerna_e_value': '1',
+            'sortmerna_max_pos': '10000', 'similarity': '0.97',
+            'sortmerna_coverage': '0.97', 'threads': '1'}],
+        ['output_params_2_OTU table | BIOM', 3, 'OTU table | BIOM']],
+     'edges': [
+        ['input_params_1_FASTQ', 'params_1'],
+        ['params_1', 'output_params_1_demultiplexed | Demultiplexed'],
+        ['output_params_1_demultiplexed | Demultiplexed', 'params_2'],
+        ['params_2', 'output_params_2_OTU table | BIOM']]},
+    {'name': 'FASTA upstream workflow', 'id': 2, 'data_types': ['18S'],
+     'description': 'This is another description',
+     'active': False, 'parameters_sample': {}, 'parameters_prep': {},
+     'nodes': [
+        ['params_3', 2, 'Split libraries', 'Defaults with Golay 12 barcodes', {
+            'min_seq_len': '200', 'max_seq_len': '1000',
+            'trim_seq_length': 'False', 'min_qual_score': '25',
+            'max_ambig': '6', 'max_homopolymer': '6',
+            'max_primer_mismatch': '0', 'barcode_type': 'golay_12',
+            'max_barcode_errors': '1.5', 'disable_bc_correction': 'False',
+            'qual_score_window': '0', 'disable_primers': 'False',
+            'reverse_primers': 'disable', 'reverse_primer_mismatches': '0',
+            'truncate_ambi_bases': 'False'}],
+        ['input_params_3_** WARNING, NOT DEFINED **', 2,
+         '** WARNING, NOT DEFINED **'],
+        ['output_params_3_demultiplexed | Demultiplexed', 2,
+         'demultiplexed | Demultiplexed'],
+        ['params_4', 3, 'Pick closed-reference OTUs', 'Defaults', {
+            'reference': '1', 'sortmerna_e_value': '1',
+            'sortmerna_max_pos': '10000', 'similarity': '0.97',
+            'sortmerna_coverage': '0.97', 'threads': '1'}],
+        ['output_params_4_OTU table | BIOM', 3, 'OTU table | BIOM']],
+     'edges': [
+        ['input_params_3_** WARNING, NOT DEFINED **', 'params_3'],
+        ['params_3', 'output_params_3_demultiplexed | Demultiplexed'],
+        ['output_params_3_demultiplexed | Demultiplexed', 'params_4'],
+        ['params_4', 'output_params_4_OTU table | BIOM']]},
+    {'name': 'Per sample FASTQ upstream workflow', 'id': 3,
+     'data_types': ['ITS'], 'description': None,
+     'active': True, 'parameters_sample': {}, 'parameters_prep': {},
+     'nodes': [
+        ['params_5', 1, 'Split libraries FASTQ', 'per sample FASTQ defaults', {
+            'max_bad_run_length': '3', 'min_per_read_length_fraction': '0.75',
+            'sequence_max_n': '0', 'rev_comp_barcode': 'False',
+            'rev_comp_mapping_barcodes': 'False', 'rev_comp': 'False',
+            'phred_quality_threshold': '3', 'barcode_type': 'not-barcoded',
+            'max_barcode_errors': '1.5', 'phred_offset': 'auto'}],
+        ['input_params_5_FASTQ', 1,
+         'FASTQ'],
+        ['output_params_5_demultiplexed | Demultiplexed', 1,
+         'demultiplexed | Demultiplexed'],
+        ['params_6', 3, 'Pick closed-reference OTUs', 'Defaults', {
+            'reference': '1', 'sortmerna_e_value': '1',
+            'sortmerna_max_pos': '10000', 'similarity': '0.97',
+            'sortmerna_coverage': '0.97', 'threads': '1'}],
+        ['output_params_6_OTU table | BIOM', 3, 'OTU table | BIOM']],
+     'edges': [
+        ['input_params_5_FASTQ', 'params_5'],
+        ['params_5', 'output_params_5_demultiplexed | Demultiplexed'],
+        ['output_params_5_demultiplexed | Demultiplexed', 'params_6'],
+        ['params_6', 'output_params_6_OTU table | BIOM']]}]
+
+
+if __name__ == "__main__":
+    main()