Ver código fonte

Finished OBOImporter unit tests

Stephen Ficklin 6 anos atrás
pai
commit
b79d1e3742

+ 0 - 190
tests/tripal_chado/example_files/go_custom_mini.obo

@@ -1,190 +0,0 @@
-format-version: 1.2
-data-version: releases/2018-08-28
-subsetdef: gocheck_do_not_annotate "Term not to be used for direct annotation"
-subsetdef: gocheck_do_not_manually_annotate "Term not to be used for direct manual annotation"
-subsetdef: goslim_agr "AGR slim"
-subsetdef: goslim_aspergillus "Aspergillus GO slim"
-subsetdef: goslim_candida "Candida GO slim"
-subsetdef: goslim_chembl "ChEMBL protein targets summary"
-subsetdef: goslim_generic "Generic GO slim"
-subsetdef: goslim_metagenomics "Metagenomics GO slim"
-subsetdef: goslim_mouse "Mouse GO slim"
-subsetdef: goslim_pir "PIR GO slim"
-subsetdef: goslim_plant "Plant GO slim"
-subsetdef: goslim_pombe "Fission yeast GO slim"
-subsetdef: goslim_synapse "synapse GO slim"
-subsetdef: goslim_yeast "Yeast GO slim"
-synonymtypedef: syngo_official_label "label approved by the SynGO project"
-synonymtypedef: systematic_synonym "Systematic synonym" EXACT
-default-namespace: gene_ontology
-remark: cvs version: $Revision: 38972$
-remark: Includes Ontology(OntologyID(Anonymous-39)) [Axioms: 277 Logical Axioms: 277]
-remark: Includes Ontology(OntologyID(OntologyIRI(<http://purl.obolibrary.org/obo/go/never_in_taxon.owl>))) [Axioms: 18 Logical Axioms: 0]
-ontology: go
-property_value: http://purl.org/dc/elements/1.1/license http://creativecommons.org/licenses/by/4.0/
-
-
-[Term]
-id: GO:0000156
-name: phosphorelay response regulator activity
-namespace: molecular_function
-def: "Responds to a phosphorelay sensor to initiate a change in cell state or activity. The activity of the response regulator is regulated by transfer of a phosphate from a histidine residue in the sensor, to an aspartate residue in the response regulator. Many but not all response regulators act as transcriptional regulators to elicit a response." [GOC:bf, PMID:10966457, PMID:11842140]
-comment: Added is_a molecular transducer activity see https://github.com/geneontology/go-ontology/issues/15611
-synonym: "two-component response regulator activity" NARROW []
-is_a: GO:0060089 ! molecular transducer activity
-relationship: part_of GO:0000160 ! phosphorelay signal transduction system
-
-
-[Term]
-id: GO:0004679
-name: AMP-activated protein kinase activity
-namespace: molecular_function
-def: "Catalysis of the reaction: ATP + a protein = ADP + a phosphoprotein. This reaction requires the presence of AMP." [GOC:mah]
-synonym: "5'-AMP-activated protein kinase activity" EXACT []
-synonym: "AMPK activity" RELATED [GOC:mah]
-synonym: "SNF1A/AMP-activated protein kinase activity" NARROW []
-xref: EC:2.7.11
-xref: Reactome:REACT_100101 "Phosphorylated AMPK phosphorylates TSC2, Danio rerio"
-xref: Reactome:REACT_100513 "Phosphorylated AMPK phosphorylates TSC2, Xenopus tropicalis"
-xref: Reactome:REACT_101641 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Arabidopsis thaliana"
-xref: Reactome:REACT_102231 "Phosphorylated AMPK phosphorylates TSC2, Bos taurus"
-xref: Reactome:REACT_104140 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Gallus gallus"
-xref: Reactome:REACT_105858 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Saccharomyces cerevisiae"
-xref: Reactome:REACT_107230 "Phosphorylation of ChREBP at Serine 568 by AMPK, Mus musculus"
-xref: Reactome:REACT_107271 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Mus musculus"
-xref: Reactome:REACT_107536 "Phosphorylated AMPK phosphorylates TSC2, Rattus norvegicus"
-xref: Reactome:REACT_11110 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Homo sapiens"
-xref: Reactome:REACT_113551 "Phosphorylation of ChREBP at Serine 568 by AMPK, Danio rerio"
-xref: Reactome:REACT_114056 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Danio rerio"
-xref: Reactome:REACT_115260 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Taeniopygia guttata"
-xref: Reactome:REACT_115507 "Phosphorylation of ChREBP at Serine 568 by AMPK, Xenopus tropicalis"
-xref: Reactome:REACT_1706 "Phosphorylation of rChREBP(Ser 568) by rAMPK, Rattus norvegicus"
-xref: Reactome:REACT_21348 "Phosphorylated AMPK phosphorylates TSC2, Homo sapiens"
-xref: Reactome:REACT_21413 "AMPK phosphorylates Raptor, Homo sapiens"
-xref: Reactome:REACT_28253 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Oryza sativa"
-xref: Reactome:REACT_31105 "Phosphorylation of ChREBP at Serine 568 by AMPK, Bos taurus"
-xref: Reactome:REACT_31214 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Canis familiaris"
-xref: Reactome:REACT_32411 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Drosophila melanogaster"
-xref: Reactome:REACT_32709 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Dictyostelium discoideum"
-xref: Reactome:REACT_33102 "Phosphorylation of ChREBP at Serine 568 by AMPK, Sus scrofa"
-xref: Reactome:REACT_349 "Phosphorylation of ChREBP at Serine 568 by AMPK, Homo sapiens"
-xref: Reactome:REACT_82669 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Rattus norvegicus"
-xref: Reactome:REACT_85819 "Phosphorylation of ChREBP at Serine 568 by AMPK, Canis familiaris"
-xref: Reactome:REACT_86300 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Xenopus tropicalis"
-xref: Reactome:REACT_86799 "Phosphorylated AMPK phosphorylates TSC2, Sus scrofa"
-xref: Reactome:REACT_89177 "Phosphorylation of ChREBP at Serine 568 by AMPK, Gallus gallus"
-xref: Reactome:REACT_93047 "Phosphorylation of ChREBP at Serine 568 by AMPK, Taeniopygia guttata"
-xref: Reactome:REACT_93827 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Schizosaccharomyces pombe"
-xref: Reactome:REACT_95348 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Sus scrofa"
-xref: Reactome:REACT_96631 "Phosphorylated AMPK phosphorylates TSC2, Taeniopygia guttata"
-xref: Reactome:REACT_96928 "Phosphorylated AMPK phosphorylates TSC2, Gallus gallus"
-xref: Reactome:REACT_97108 "Phosphorylated AMPK phosphorylates TSC2, Canis familiaris"
-xref: Reactome:REACT_97911 "Phosphorylated AMPK phosphorylates TSC2, Drosophila melanogaster"
-xref: Reactome:REACT_98167 "pAMPK inactivates ACC2 inhibiting malonyl-CoA synthesis, Bos taurus"
-xref: Reactome:REACT_99741 "Phosphorylated AMPK phosphorylates TSC2, Mus musculus"
-is_a: GO:0004674 ! protein serine/threonine kinase activity
-is_a: GO:0060089 ! molecular transducer activity
-
-
-[Term]
-id: GO:0005072
-name: transforming growth factor beta receptor, cytoplasmic mediator activity
-namespace: molecular_function
-def: "Activity of any of the molecules that transmit the signal from a TGF-beta receptor through the cytoplasm to the nucleus." [GOC:hjd]
-comment: Note that this term and its children are useful for annotating proteins of the SMAD family.
-synonym: "TGF-beta receptor, cytoplasmic mediator activity" EXACT []
-synonym: "TGFbeta receptor, cytoplasmic mediator activity" EXACT []
-is_a: GO:0060089 ! molecular transducer activity
-
-[Term]
-id: GO:0003674
-name: molecular_function
-namespace: molecular_function
-alt_id: GO:0005554
-def: "A molecular process that can be carried out by the action of a single macromolecular machine, usually via direct physical interactions with other molecular entities. Function in this sense denotes an action, or activity, that a gene product (or a complex) performs. These actions are described from two distinct but related perspectives: (1) biochemical activity, and (2) role as a component in a larger system/process." [GOC:pdt]
-comment: Note that, in addition to forming the root of the molecular function ontology, this term is recommended for use for the annotation of gene products whose molecular function is unknown. When this term is used for annotation, it indicates that no information was available about the molecular function of the gene product annotated as of the date the annotation was made; the evidence code "no data" (ND), is used to indicate this. Despite its name, this is not a type of 'function' in the sense typically defined by upper ontologies such as Basic Formal Ontology (BFO). It is instead a BFO:process carried out by a single gene product or complex.
-subset: goslim_aspergillus
-subset: goslim_candida
-subset: goslim_chembl
-subset: goslim_generic
-subset: goslim_metagenomics
-subset: goslim_pir
-subset: goslim_plant
-subset: goslim_yeast
-synonym: "molecular function" EXACT []
-
-
-[Term]
-id: GO:0060089
-name: molecular transducer activity
-namespace: molecular_function
-def: "A compound molecular function in which an effector function is controlled by one or more regulatory components." [GOC:dos, GOC:pdt]
-subset: gocheck_do_not_manually_annotate
-subset: goslim_pir
-is_a: GO:0003674 ! molecular_function
-
-[Term]
-id: GO:0004690
-name: cyclic nucleotide-dependent protein kinase activity
-namespace: molecular_function
-def: "Catalysis of the reaction: ATP + a protein = ADP + a phosphoprotein. This reaction requires the presence of a cyclic nucleotide." [GOC:mah]
-xref: EC:2.7.11
-is_a: GO:0004674 ! protein serine/threonine kinase activity
-is_a: GO:0060089 ! molecular transducer activity
-
-[Term]
-id: GO:0009927
-name: histidine phosphotransfer kinase activity
-namespace: molecular_function
-def: "Serves as a phospho-His intermediate enabling the transfer of phospho group between a hybrid kinase and a response regulator." [PMID:11842140]
-comment: Added is_a molecular transducer activity see https://github.com/geneontology/go-ontology/issues/15611
-is_a: GO:0004672 ! protein kinase activity
-is_a: GO:0060089 ! molecular transducer activity
-
-[Term]
-id: GO:0017132
-name: cAMP-dependent guanyl-nucleotide exchange factor activity
-namespace: molecular_function
-def: "Stimulates the exchange of guanyl nucleotides associated with a GTPase, when activated by cAMP binding." [GOC:mah, PMID:9856955]
-is_a: GO:0005085 ! guanyl-nucleotide exchange factor activity
-is_a: GO:0060089 ! molecular transducer activity
-
-[Term]
-id: GO:0031992
-name: energy transducer activity
-namespace: molecular_function
-def: "The biological transducer activity that accepts energy and converts it to another form, often by transfer to another molecule within the cell." [GOC:go_curators]
-subset: goslim_pir
-synonym: "light harvesting activity" RELATED []
-synonym: "photon capture" RELATED []
-is_a: GO:0060089 ! molecular transducer activity
-
-[Term]
-id: GO:0038023
-name: signaling receptor activity
-namespace: molecular_function
-alt_id: GO:0004872
-alt_id: GO:0019041
-def: "Receiving a signal and transmitting it in the cell to initiate a change in cell activity. A signal is a physical entity or change in state that is used to transfer information in order to trigger a response." [GOC:bf, GOC:signaling]
-subset: goslim_agr
-subset: goslim_chembl
-subset: goslim_metagenomics
-subset: goslim_mouse
-subset: goslim_pir
-subset: goslim_plant
-synonym: "receptor activity" BROAD []
-synonym: "receptor activity involved in signal transduction" EXACT [GOC:bf]
-is_a: GO:0060089 ! molecular transducer activity
-created_by: rfoulger
-creation_date: 2011-08-01T02:45:27Z
-
-[Term]
-id: GO:0097472
-name: cyclin-dependent protein kinase activity
-namespace: molecular_function
-def: "Catalysis of the phosphorylation of an amino acid residue in a protein, usually according to the reaction: a protein + ATP = a phosphoprotein + ADP. This reaction requires the binding of a regulatory cyclin subunit and full activity requires stimulatory phosphorylation by a CDK-activating kinase (CAK)." [GOC:pr]
-is_a: GO:0004672 ! protein kinase activity
-is_a: GO:0060089 ! molecular transducer activity
-relationship: part_of GO:0051726 ! regulation of cell cycle
-created_by: paola
-creation_date: 2013-03-06T13:46:04Z

+ 0 - 18
tests/tripal_chado/example_files/pto_colon.obo

@@ -1,18 +0,0 @@
-format-version: 1.2
-data-version: releases/2018-03-09
-saved-by: cooperl
-default-namespace: core_test_PTO_mini
-import: http://purl.obolibrary.org/obo/to/imports/chebi_import.owl
-
-ontology: to
-
-
-[Term]
-id: CHEBI:132502 ! fatty acid 18:3
-
-
-[Term]
-id: TO:1000066
-name: shoot system nickel content
-def: "A nickel content trait (TO:0006051) which is the nickel cation (CHEBI:25516) composition in a shoot system (PO:0009006)." [https://search.proquest.com/docview/1426182399, TO:cooperl]
-synonym: "shoot Ni content (related)" RELATED []

+ 36 - 38
tests/tripal_chado/example_files/cvtermpath_test.obo → tests/tripal_chado/example_files/test.obo

@@ -1,121 +1,119 @@
 format-version: 1.2
-default-namespace: cvtermpath_test
-ontology: cvtp
+default-namespace: tripal_obo_test
+ontology: tot
 subsetdef: test_normal "Normal nodes"
 subsetdef: test_crazy "Crazy nodes"
 
 [Term]
-id: CVTP:001
+id: TOT:001
 name: node01
 def: This is node 1
 subset: test_normal
 
 [Term]
-id: CVTP:002
+id: TOT:002
 name: node02
-is_a: CVTP:001
+is_a: TOT:001
 def: This is node 2
 subset: test_normal
 
 [Term]
-id: CVTP:003
+id: TOT:003
 name: node03
-is_a: CVTP:001
+is_a: TOT:001
 def: This is node 3
 subset: test_normal
 
 [Term]
-id: CVTP:004
+id: TOT:004
 name: node04
-is_a: CVTP:001
+is_a: TOT:001
 def: This is node 4
 subset: test_normal
-relationship: has_part CVTP:011
+relationship: has_part TOT:011
 
 
 [Term]
-id: CVTP:005
+id: TOT:005
 name: node05
-is_a: CVTP:001
+is_a: TOT:001
 def: This is node 5
 subset: test_normal
 
 [Term]
-id: CVTP:006
+id: TOT:006
 name: node06
-is_a: CVTP:003
+is_a: TOT:003
 def: This is node 6
 subset: test_normal
 
 [Term]
-id: CVTP:007
+id: TOT:007
 name: node07
-is_a: CVTP:003
+is_a: TOT:003
 def: This is node 7
 subset: test_normal
 
 [Term]
-id: CVTP:008
+id: TOT:008
 name: node08
-is_a: CVTP:007
+is_a: TOT:007
 def: This is node 8
 subset: test_normal
 
 [Term]
-id: CVTP:009
+id: TOT:009
 name: node09
-is_a: CVTP:004
-is_a: CVTP:007
+is_a: TOT:004
+is_a: TOT:007
 def: This is node 9
 subset: test_normal
 
 [Term]
-id: CVTP:010
+id: TOT:010
 name: node10
-is_a: CVTP:005
+is_a: TOT:005
 def: This is node 10
 subset: test_normal
 
 [Term]
-id: CVTP:011
+id: TOT:011
 name: node11
-is_a: CVTP:009
-is_a: CVTP:010
-def: This is node 11
+is_a: TOT:009
+is_a: TOT:010
+def: This is node 11 : Yo ! this comment should be ignored.
 synonym: "crazy node" EXACT []
 xref: GO:0043226
 subset: test_crazy
+comment: This is a crazy node!
 
 
 [Term]
-id: CVTP:012
+id: TOT:012
 name: node12
-is_a: CVTP:010
+is_a: TOT:010
 def: This is node 12
 subset: test_normal
 
 [Term]
-id: CVTP:013
+id: TOT:013
 name: node13
-is_a: CVTP:011
+is_a: TOT:011
 def: This is node 13
 subset: test_normal
 
 [Term]
-id: CVTP:014
+id: TOT:014
 name: node14
 is_obsolete: true
 def: This is node 14
 
+[Term]
+id: CHEBI:132502 ! fatty acid 18:3
+
 [Typedef]
 id: has_part
 name: has_part
 namespace: external
 xref: BFO:0000051
 is_transitive: true
-
-
-
-
-
-

+ 523 - 320
tests/tripal_chado/loaders/OBOImporterTest.php

@@ -10,394 +10,597 @@ class OBOImporterTest extends TripalTestCase {
   // Uncomment to auto start and rollback db transactions per test method.
   use DBTransaction;
 
-
   /**
-   * Tests that the Goslim ontology loads using a remote URL.  Ensure subgroups
-   * load.
+   * A helper function for loading any OBO.
+   *
+   * @param $name - ontology name.  This goes in the tripal_cv_obo table.
+   * @param $path - path to the OBO.  this can be a file path or a URL.
+   *
+   * @throws \Exception
+   */
+  private function loadOBO($name, $path) {
+    
+    $obo_id = db_select('public.tripal_cv_obo', 't')
+    ->fields('t', ['obo_id'])
+    ->condition('t.name', $name)
+    ->execute()
+    ->fetchField();
+    
+    if (!$obo_id) {
+      
+      $obo_id = db_insert('public.tripal_cv_obo')
+      ->fields(['name' => $name, 'path' => $path])
+      ->execute();
+    }
+    
+    $run_args = ['obo_id' => $obo_id];
+    
+    module_load_include('inc', 'tripal_chado', 'includes/TripalImporter/OBOImporter');
+    $importer = new \OBOImporter();
+    $importer->create($run_args);
+    $importer->prepareFiles();
+    $importer->run();
+  }
+  
+  
+  /**
+   * Tests that an OBO from a remote URL can be loaded.  
+   * 
+   * For this test we will use the GO Plant Slim.
    *
    * @group obo
    */
-
-  public function testGO_SLIM_load() {
+ /*  public function testRemoteOBO() {
 
     $name = 'core_test_goslim_plant';
     $path = 'http://www.geneontology.org/ontology/subsets/goslim_plant.obo';
 
-    $this->load_obo($name, $path);
+    $this->loadOBO($name, $path);
 
-    $exists = db_select('chado.cv', 'c')
+    // Test that we get all three vocabularies added:  biological_process,
+    // cellular_component and molecular_function.
+    $bp_cv_id = db_select('chado.cv', 'c')
       ->fields('c', ['cv_id'])
       ->condition('name', 'biological_process')
       ->execute()
       ->fetchField();
-    $this->assertNotFalse($exists);
+    $this->assertNotFalse($bp_cv_id, 
+      "Missing the 'biological_process' cv record after loading the GO plant slim.");
 
-    $exists = db_select('chado.cv', 'c')
+    $cc_cv_id = db_select('chado.cv', 'c')
       ->fields('c', ['cv_id'])
       ->condition('name', 'cellular_component')
       ->execute()
       ->fetchField();
-    $this->assertNotFalse($exists);
+    $this->assertNotFalse($cc_cv_id,
+      "Missing the 'cellular_component' cv record after loading the GO plant slim.");
 
-    $exists = db_select('chado.cv', 'c')
+    $mf_cv_id = db_select('chado.cv', 'c')
       ->fields('c', ['cv_id'])
       ->condition('name', 'molecular_function')
       ->execute()
       ->fetchField();
-    $this->assertNotFalse($exists);
-
-
-    $sql = "
-      SELECT DISTINCT CVTP.value
-      FROM {cvtermprop} CVTP
-        INNER JOIN {cvterm} CVTPT on CVTPT.cvterm_id = CVTP.type_id
-        INNER JOIN {cvterm} CVT on CVT.cvterm_id = CVTP.cvterm_id
-        INNER JOIN {dbxref} DBX on CVT.dbxref_id = DBX.dbxref_id
-        INNER JOIN {db} DB on DB.db_id = DBX.db_id
-      WHERE CVTPT.name = 'Subgroup' and DB.name = 'GO' and CVTP.value = 'goslim_plant'
-    ";
-    $exists = chado_query($sql)->fetchField();
-    $this->assertNotFalse($exists);
-  }
-
-
+    $this->assertNotFalse($mf_cv_id,
+      "Missing the 'molecular_function' cv record after loading the GO plant slim.");
+    
+    // Make sure we have a proper database record.
+    $go_db_id = db_select('chado.db', 'd')
+      ->fields('d', ['db_id'])
+      ->condition('name', 'GO')
+      ->execute()
+      ->fetchField();
+    $this->assertNotFalse($go_db_id,
+      "Missing the 'GO' database record after loading the GO plant slim.");
+  } */
+  
   /**
-   * @param $name - ontology name.  This goes in the tripal_cv_obo table.
-   * @param $path - path to the OBO.  this can be a file path or a URL.
+   * Tests that an OBO from a local path can be loaded.
    *
-   * @throws \Exception
+   * For this test we will use a test ontology.
+   *
+   * @group obo
    */
-
-  private function load_obo($name, $path) {
-
-    $obo_id = db_select('public.tripal_cv_obo', 't')
-      ->fields('t', ['obo_id'])
-      ->condition('t.name', $name)
+  public function testLocalOBO() {
+    $name = 'tripal_obo_test';
+    $path = __DIR__ . '/../example_files/test.obo';
+    
+    $this->loadOBO($name, $path);
+    
+    // Make sure we have a proper vocabulary record.
+    $tot_cv_id = db_select('chado.cv', 'c')
+      ->fields('c', ['cv_id'])
+      ->condition('name', 'tripal_obo_test')
       ->execute()
       ->fetchField();
-
-    if (!$obo_id) {
-
-      $obo_id = db_insert('public.tripal_cv_obo')
-        ->fields(['name' => $name, 'path' => $path])
-        ->execute();
-    }
-
-    $run_args = ['obo_id' => $obo_id];
-
-    module_load_include('inc', 'tripal_chado', 'includes/TripalImporter/OBOImporter');
-    $importer = new \OBOImporter();
-    $importer->create($run_args);
-    $importer->prepareFiles();
-    $importer->run();
-
+    $this->assertNotFalse($tot_cv_id,
+      "Missing the 'tripal_obo_test' cv record after loading the test.obo file");
+    
+    // Make sure we have a proper database record.
+    $tot_db_id = db_select('chado.db', 'd')
+      ->fields('d', ['db_id'])
+      ->condition('name', 'TOT')
+      ->execute()
+      ->fetchField();
+    $this->assertNotFalse($tot_db_id,
+      "Missing the 'TOT' db record after loading the test.obo file");
+    
+    return [[$tot_cv_id, $tot_db_id]];
   }
 
   /**
-   * Ensure SO can be loaded.  Ensure that synonyms are set properly.
-   *
+   * Test that all nodes in our test OBO are loaded.
+   * 
    * @group obo
-   * @ticket 525
+   * @dataProvider testLocalOBO
    */
-  public function test_relationships_in_SO_exist() {
 
-    // step 1: drop the SO CV and CASCADE.
+  public function testCVterms($cv_id, $db_id) {
 
-    $result = chado_query("SET search_path to public, chado;
-    DELETE FROM {cv} WHERE name = 'sequence'");
-    $result = chado_query("SET search_path to public, chado;
-    DELETE FROM {db} WHERE name = 'SO'");
-
-    // step 2: re-add SO.
-    $name = 'Sequence Ontology';
-    $path = 'http://purl.obolibrary.org/obo/so.obo';
-
-    $this->load_obo($name, $path);
-
-    $sql = "SELECT CVT.name, CVTSYN.synonym
-FROM {cvterm} CVT
-  INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
-  INNER JOIN {db} on DB.db_id = DBX.db_id
-  LEFT JOIN {cvtermsynonym} CVTSYN on CVTSYN.cvterm_id = CVT.cvterm_id
-WHERE DB.name = 'SO' and CVT.name = 'supercontig'
-ORDER BY DBX.accession";
-
-
-    $results = chado_query($sql)->fetchAll();
-    $result = $results[0];
+    // Our test OBO has 14 nodes.
+    $nodes = [
+      ['TOT:001' => 'node01'], 
+      ['TOT:002' => 'node02'], 
+      ['TOT:003' => 'node03'], 
+      ['TOT:004' => 'node04'], 
+      ['TOT:005' => 'node05'], 
+      ['TOT:006' => 'node06'],
+      ['TOT:007' => 'node07'], 
+      ['TOT:008' => 'node08'], 
+      ['TOT:009' => 'node09'],
+      ['TOT:010' => 'node10'], 
+      ['TOT:011' => 'node11'], 
+      ['TOT:012' => 'node12'], 
+      ['TOT:013' => 'node13'],
+      ['TOT:014' => 'node14'],
+    ];
 
-    $this->assertNotNull($result);
-    $this->assertNotEmpty($result);
-    $this->assertEquals("supercontig", $result->name);
-    $this->assertEquals("scaffold", $result->synonym);
+    // Test that the proper records were added to identify the term.    
+    foreach ($nodes as $id => $node_name) {
+      
+      // Check that cvterm record is inserted.
+      $cvterm_id = db_select('chado.cvterm', 'cvt')
+        ->fields('cvt', ['cvterm_id'])
+        ->condition('cvt.name', $node_name)
+        ->condition('cvt.cv_id', $cv_id)
+        ->execute()
+        ->fetchField();
+      $this->assertNotFalse($cvterm_id,
+        "Missing the cvterm record with name, '$node' after loading the test.obo file");
+      
+      // Check that the dbxref record is inserted.
+      $accession = preg_replace('/TOT:/', '', $id);
+      $dbxref_id = db_select('chado.dbxref', 'dbx')
+        ->fields('dbx', ['dbxref_id'])
+        ->condition('accession', $accession)
+        ->condition('db_id', $db_id);
+      $this->assertNotFalse($cvterm_id,
+        "Missing the dbxref record forid, '$id' after loading the test.obo file");
+    }
+    
+    // Test node 11 to make sure the definition was inserted correctly.
+    // The definition for node11 has an extra colon and a comment.  The colon
+    // should not throw off the insertion of the full definition and
+    // the comment should be excluded.
+    $def = db_select('chado.cvterm', 'cvt')
+      ->fields('cvt', ['definition'])
+      ->condition('cvt.name', 'node11')
+      ->condition('cvt.cv_id', $cv_id)
+      ->execute()
+      ->fetchField();
+    $this->assertNotFalse($def,
+      "The definition for node11 was not added.");
+    $this->assertEquals('This is node 11 : Yo', $def,
+      "The definition for node11 is incorrect. it was stored as \"$def\" but should be \"def: This is node 11 : Yo\".");
+    
+    // Make sure that colons in term names don't screw up the term. This test
+    // corresponds to the term with id CHEBI:132502 in the test.obo file.
+    $exists = db_select('chado.cv', 'c')
+      ->fields('c', ['cv_id'])
+      ->condition('name', 'fatty acid 18')
+      ->execute()
+      ->fetchField();
+    $this->assertFalse($exists);
+    
+    
+    // Node14 should be marked as obsolete.
+    $sql = "
+      SELECT CVT.is_obsolete
+      FROM {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE DB.name = 'TOT' and DBX.accession = '014'
+    ";
+    $is_obsolete = chado_query($sql)->fetchField();
+    $this->assertEquals(1, $is_obsolete,
+      "The term, node14, should be marked as obsolete after loading of the test.obo file.");
+    
+    // Every vocabulary should have an is_a term added to support the is_a
+    // relationships.
+    $sql = "
+      SELECT CVT.is_relationshiptype
+      FROM {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE CVT.name = 'is_a' and DB.name = 'TOT'
+    ";
+    $is_reltype = chado_query($sql)->fetchField();
+    $this->assertNotFalse($is_reltype,
+      "The cvterm record for, is_a, should have been added during loading of the test.obo file.");
+    $this->assertEquals(1, $is_reltype, 
+      "The cvterm record, is_a, should be marked as a relationship type.");
+    
   }
-
-
+  
   /**
-   * Test simply that nodes are inserted.
-   ** @group obo
+   * Test that insertion of synonyms works.
+   * 
+   * The term 'node11' has a synonym:"crazy node" EXACT []
+   * 
+   * @group obo
+   * @dataProvider testLocalOBO
+   */
+  public function testSynonyms($cv_id, $db_id){
+     
+    $query = db_select('chado.cvtermsynonym', 'cvts');
+    $query->fields('cvts', ['synonym']);
+    $query->join('chado.cvterm', 'cvt', 'cvts.cvterm_id = cvt.cvterm_id');
+    $query->condition('cvt.name', 'node11');
+    $synonym = $query->execute()->fetchField();
+    $this->assertNotFalse($synonym,
+      "Failed to find the 'crazy node' synonym record for node 11 after loading the test.obo file.");
+    
+    $this->assertEquals("crazy node", $synonym,
+      "Failed to properly add the 'crazy node' synonym for node 11 instead the following was loaded: $synonym");
+  }
+  
+  /**
+   * Test that insertion of subset works.
+   *
+   * The term 'node11' belongs to the test_crazy subset. Everything else belongs
+   * to the test_normal subset.
+   * 
    *
+   * @group obo
+   * @dataProvider testLocalOBO
    */
-
-  public function test_cvtermpath_cv_nodes_inserted() {
-
-    $name = 'path_test_mini';
-    $path = __DIR__ . '/../example_files/cvtermpath_test.obo';
-    $this->load_obo($name, $path);
-
-    //Check cvtermpath is sane.
-
-    $cv_name = 'cvtermpath_test';
-
-
-    $nodes = [
-      'node01',
-      'node02',
-      'node03',
-      'node04',
-      'node05',
-      'node06',
-      'node07',
-      'node08',
-      'node09',
-      'node10',
-      'node11',
-      'node12',
-      'node13',
-      'node14',
-    ];
-
-    //check nodes are inserted.
-    foreach ($nodes as $node) {
-
-      $query = db_select('chado.cvterm', 'cvt')
-        ->fields('cvt', ['cvterm_id', 'cv_id'])
-        ->condition('cvt.name', $node);
-      $query->join('chado.cv', 'cv', 'cvt.cv_id = cv.cv_id');
-      $query->condition('cv.name', $cv_name);
-      $result = $query->execute()
-        ->fetchObject();
-      $this->assertNotFalse($result);
-
-    }
+  public function testSubset($cv_id, $db_id) {
+    
+    $sql = "
+      SELECT CVT.name
+      FROM {cvtermprop} CVTP
+        INNER JOIN {cvterm} CVTPT on CVTPT.cvterm_id = CVTP.type_id
+        INNER JOIN {cvterm} CVT on CVT.cvterm_id = CVTP.cvterm_id
+        INNER JOIN {dbxref} DBX on CVT.dbxref_id = DBX.dbxref_id
+        INNER JOIN {db} DB on DB.db_id = DBX.db_id
+      WHERE CVTPT.name = 'Subgroup' and DB.name = 'TOT' and CVTP.value = 'test_crazy'
+    ";
+    $term_name = chado_query($sql)->fetchField();
+    $this->assertNotFalse($term_name,
+      "This cvtermprop record for the subset 'test_crazy' is missing.");
+    
+    $this->assertEquals('node11', $term_name,
+      "This cvtermprop record for the subset 'test_crazy' is assigned to term, $term_name, instead of node11.");
+  
+    $sql = "
+      SELECT count(CVT.cvterm_id)
+      FROM {cvtermprop} CVTP
+        INNER JOIN {cvterm} CVTPT on CVTPT.cvterm_id = CVTP.type_id
+        INNER JOIN {cvterm} CVT on CVT.cvterm_id = CVTP.cvterm_id
+        INNER JOIN {dbxref} DBX on CVT.dbxref_id = DBX.dbxref_id
+        INNER JOIN {db} DB on DB.db_id = DBX.db_id
+      WHERE CVTPT.name = 'Subgroup' and DB.name = 'TOT' and CVTP.value = 'test_normal'
+    ";
+    $subset_count = chado_query($sql)->fetchField();
+    
+    $this->assertNotFalse($subset_count,
+      "This cvtermprop record for the subset 'test_normal' are missing.");
+    
+    // There should be 12 terms that belong to subset 'test_normal' as node14
+    // does not belong to a subset.
+    $this->assertEquals(12, $subset_count,
+      "There are $subset_count cvtermprop record for the subset 'test_normal' but there should be 13.");
   }
-
-
+  
   /**
-   * This data provider currently returns an array of data in the following manner:
-   * item[0] - the object node
-   * item[1] - an array containing a list of subject nodes, ie, nodes that claim they have a "is_a" relationship with this node.
+   * Test that the insertion of xref works.
+   *
+   * The term 'node11' belongs to the test_crazy subset. Everything else belongs
+   * to the test_normal subset.
    *
-   * @return array
+   *
+   * @group obo
+   * @dataProvider testLocalOBO
    */
-  public function node_data_provider() {
-
-    $data = [
-      [
-        'node01',// object
-        [ //subjects
-          'node02',
-          'node03',
-          'node04',
-          'node05',
-          'node06',
-          'node07',
-          'node08',
-          'node09',
-          'node10',
-          'node11',
-          'node12',
-          'node13',
-          //   'node14',
-          //Node 14 is not connected!
-        ],
-      ],
-
-      [
-        'node04',
-        ['node09','node11'],
-      ],
-      [
-        'node11',
-        ['node13',],
-      ],
-    ];
-    return $data;
-
+  public function testXref($cv_id, $db_id) {
+    
+    $sql = "
+      SELECT concat(DB2.name, ':', DBX2.accession)
+      FROM {cvterm} CVT
+        INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+        INNER JOIN {db} on DB.db_id = DBX.db_id
+        INNER JOIN {cvterm_dbxref} CVTDBX on CVTDBX.cvterm_id = CVT.cvterm_id
+        INNER JOIN {dbxref} DBX2 on DBX2.dbxref_id = CVTDBX.dbxref_id
+        INNER JOIN {db} DB2 on DB2.db_id = DBX2.db_id
+      WHERE DB.name = 'TOT' and CVT.name = 'node11'
+      ORDER BY DBX.accession
+    ";
+    $xref_id = chado_query($sql)->fetchField();
+    $this->assertNotFalse($xref_id,
+      "This cvterm_dbxref record for the xref 'GO:0043226' is missing for node11.");
+    
+    $this->assertEquals('GO:0043226', $xref_id,
+      "This cvterm_dbxref record for node 11 is, $xref_id, instead of GO:0043226.");
   }
-
+  
   /**
+   * Test that the insertion of comments works.
+   *
+   * The term 'node11' contains a comment.
+   *
    * @group obo
-   * @dataProvider node_data_provider
+   * @dataProvider testLocalOBO
    */
-  public function test_cvtermpath_correct($object, $subjects) {
-
-    $name = 'path_test_mini';
-    $path = __DIR__ . '/../example_files/cvtermpath_test.obo';
-    $this->load_obo($name, $path);
-
-
-    $cv_name = 'cvtermpath_test';
-
-    $cv_id = chado_get_cv(['name' => $cv_name])->cv_id;
-
-    //populate cvtermpath
-    chado_update_cvtermpath($cv_id);
-
-
-    $query = db_select('chado.cvtermpath', 'cp');
-    $query->fields('cp', ['pathdistance']);
-    $query->condition('cp.cv_id', $cv_id);
-    $query->join('chado.cvterm', 'subject', 'cp.subject_id = subject.cvterm_id');
-    $query->join('chado.cvterm', 'object', 'cp.object_id = object.cvterm_id');
-    $query->condition('object.name', $object);
-    $query->fields('subject', ['name']);
-
-    //First, ensure that the number of relationships is correct
-
-    $countquery = clone $query;
-
-    $results = $countquery->execute()->fetchAll();
-
-
-    $this->assertEquals(count($subjects), count($results));
-
-
-
-    foreach ($subjects as $subject) {
-
-      $query_copy = clone $query;
-
-      $query_copy->condition('subject.name', $subject);
-      $results = $query_copy->execute()->fetchObject();
-
-      $this->assertNotFalse($results, "failed for {$object} as object and {$subject} as subject.");
-
-    }
+  public function testComment($cv_id, $db_id) {
+    
+    $sql = "
+      SELECT CVTP.value
+      FROM {cvterm} CVT
+        INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+        INNER JOIN {db} on DB.db_id = DBX.db_id
+        INNER JOIN {cvtermprop} CVTP on CVTP.cvterm_id = CVT.cvterm_id
+        INNER JOIN {cvterm} CVTPT on CVTPT.cvterm_id = CVTP.type_id
+      WHERE DB.name = 'TOT' and CVTPT.name = 'comment' and CVT.name = 'node11'
+      ORDER BY DBX.accession
+    ";
+    $comment = chado_query($sql)->fetchField();
+    $this->assertNotFalse($xref_id,
+      "This cvterm_dbxref record for the xref 'This is a crazy node' is missing for node11.");
+    
+    $this->assertEquals('This is a crazy node', $comment,
+      "This cvterm_dbxref record for node11 is, \"$comment\", instead of \"This is a crazy node\".");
   }
-
+  
   /**
-   * ONLY node 1 should be root for test OBO.
+   * Tests that the cvtermpath is properly loaded.
    *
    * @group obo
+   * @dataProvider testLocalOBO
    */
-  public function test_cvtermpath_mview_root_terms_correct() {
-
-    $name = 'path_test_mini';
-    $path = __DIR__ . '/../example_files/cvtermpath_test.obo';
-    $this->load_obo($name, $path);
-
-    //populate mview
-    chado_populate_mview(chado_get_mview_id('cv_root_mview'));
-
-
-    $cv_name = 'cvtermpath_test';
-
-    $roots = db_select('chado.cv_root_mview', 't')
-      ->fields('t', ['name'])
-      ->condition('cv_name', $cv_name)
-      ->execute()
-      ->fetchAll();
-
-    $this->assertNotEmpty($roots);
-
-    $this->assertLessThan(2, count($roots));
-    $this->assertEquals("node01", $roots[0]->name);
-
+  public function testRelationships($cv_id, $db_id) {
+    $relationships = [
+      ['node02', 'is_a', 'node01'],
+      ['node03', 'is_a', 'node01'],
+      ['node04', 'is_a', 'node01'],
+      ['node04', 'has_part', 'node11'],
+      ['node05', 'is_a', 'node01'],
+      ['node06', 'is_a', 'node03'],
+      ['node07', 'is_a', 'node03'],
+      ['node08', 'is_a', 'node07'],
+      ['node09', 'is_a', 'node04'],
+      ['node09', 'is_a', 'node07'],
+      ['node10', 'is_a', 'node05'],
+      ['node11', 'is_a', 'node09'],
+      ['node11', 'is_a', 'node10'],
+      ['node12', 'is_a', 'node10'],
+      ['node13', 'is_a', 'node11'],
+    ];
+    foreach ($relationships  as $relationship) {
+      $subject = $relationship[0];
+      $type = $relationship[1];
+      $object = $relationship[2];
+      $sql = "
+        SELECT CVTR.cvterm_relationship_id
+        FROM {cvterm} CVT
+          INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+          INNER JOIN {db} on DB.db_id = DBX.db_id
+          INNER JOIN {cvterm_relationship} CVTR on CVTR.subject_id = CVT.cvterm_id
+          INNER JOIN {cvterm} CVT2 on CVT2.cvterm_id = CVTR.object_id
+          INNER JOIN {cvterm} CVT3 on CVT3.cvterm_id = CVTR.type_id
+        WHERE DB.name = 'TOT' AND CVT2.name = :object AND 
+          CVT3.name = :type AND CVT.name = :subject
+      ";
+      $args = [':object' => $object, ':type' => $type, ':subject' => $subject];
+      $rel_id = chado_query($sql, $args)->fetchField();
+      $this->assertNotFalse($rel_id,
+        "The following relationship could not be found: $subect $type $object.");
+    }
+    
+    // Now make sure we have no more relationships than what we are supposed
+    // to have.
+    $sql = "
+      SELECT count(CVTR.cvterm_relationship_id)
+      FROM {cvterm} CVT
+        INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+        INNER JOIN {db} on DB.db_id = DBX.db_id
+        INNER JOIN {cvterm_relationship} CVTR on CVTR.object_id = CVT.cvterm_id
+      WHERE DB.name = 'TOT' AND CVT.is_relationshiptype = 0
+    ";
+    $rel_count = chado_query($sql)->fetchField();
+    $expected = count($relationships);
+    $this->assertEquals($expected, $rel_count,
+      "There are an incorrect number of relationships. There were $rel_count found but there should be $expected.");
   }
 
   /**
-   * Test OBO has a synonym.  check its inserted properly.
+   * Tests that the cvtermpath is properly loaded.
+   * 
    * @group obo
-   * @group wip
+   * @dataProvider testLocalOBO
    */
-  public function test_synonyms_are_loaded(){
-    //node11 has a synonym:"crazy node" EXACT []
-
-
-    $name = 'path_test_mini';
-    $path = __DIR__ . '/../example_files/cvtermpath_test.obo';
-    $this->load_obo($name, $path);
-
-    $cv_name = 'cvtermpath_test';
-
-    $query = db_select('chado.cvtermsynonym', 't')
-      ->fields('t', ['synonym']);
-    $query->join('chado.cvterm', 'cvt', 't.cvterm_id = cvt.cvterm_id');
-    $query->condition('cvt.name', 'node11');
-
-    $result = $query->execute()->fetchField();
-
-    $this->assertNotFalse($result);
-
-    $this->assertEquals("crazy node", $result);
-
-
+  public function testCVtermPath($cv_id, $db_id) {
+    
+    // For now we won't include distance or type in the check because depending
+    // how the tree was loaded and if there are multiple paths to a node
+    // then there's no guarantee we'll always get the same path. Therefore the
+    // type and pathdistance may be different (althoug not incorrect).
+    $relationships = [
+      // Node01 as root: note that the root term always has a link to itself
+      // in the cvtermpath table.
+      ['node01', 'node01'],
+      ['node01', 'node02'],
+      ['node01', 'node03'],
+      ['node01', 'node04'],
+      ['node01', 'node05'],
+      ['node01', 'node06'],
+      ['node01', 'node07'],
+      ['node01', 'node08'],
+      ['node01', 'node09'],
+      ['node01', 'node10'],
+      ['node01', 'node11'],
+      ['node01', 'node12'],
+      ['node01', 'node13'],
+      // Node03 as root.
+      ['node03', 'node04'], 
+      ['node03', 'node06'],
+      ['node03', 'node07'],
+      ['node03', 'node08'],
+      ['node03', 'node09'],
+      ['node03', 'node11'],
+      ['node03', 'node13'],
+      // Node04 as root.
+      ['node04', 'node09'],
+      ['node04', 'node11'],
+      ['node04', 'node13'],
+      // Node05 as root.
+      ['node05', 'node04'],
+      ['node05', 'node09'],
+      ['node05', 'node10'],
+      ['node05', 'node11'],
+      ['node05', 'node12'],
+      ['node05', 'node13'],
+      // Node07 as root.
+      ['node07', 'node04'],
+      ['node07', 'node08'],
+      ['node07', 'node09'],
+      ['node07', 'node11'],
+      ['node07', 'node13'],
+      // Node09 as root.
+      ['node09', 'node04'],
+      ['node09', 'node11'],
+      ['node09', 'node13'],
+      // Node10 as root.
+      ['node10', 'node04'],
+      ['node10', 'node09'],
+      ['node10', 'node11'],
+      ['node10', 'node12'],
+      ['node10', 'node13'],
+      // Node11 as root.
+      ['node11', 'node04'],
+      ['node11', 'node09'],
+      ['node11', 'node13'],
+    ];
 
+    // Populate the cvtermpath for our test OBO.
+    chado_update_cvtermpath($cv_id);
+    
+    foreach ($relationships as $relationship) {
+      $object = $relationship[0];
+      $subject = $relationship[1];
+      $sql = "
+        SELECT cvtermpath_id
+        FROM {cvtermpath} CVTP 
+          INNER JOIN {cvterm} CVTO on CVTO.cvterm_id = CVTP.object_id
+          INNER JOIN {cvterm} CVTS on CVTS.cvterm_id = CVTP.subject_id
+          INNER JOIN {cvterm} CVTT on CVTT.cvterm_id = CVTP.type_id
+        WHERE CVTP.cv_id = :cv_id and CVTO.name = :object and 
+          CVTS.name = :subject
+      ";
+      $args = [':cv_id' => $cv_id, ':object' => $object, ':subject' => $subject];
+      $cvtermpath_id = chado_query($sql, $args)->fetchField();
+      $this->assertNotFalse($cvtermpath_id,
+        "Cound not find the cvtermpath record for the relationship: $subject => $object.");
+    }
 
+    // Now make sure we have no additional entries.
+    $sql = "
+          SELECT count(cvtermpath_id)
+          FROM {cvtermpath} CVTP
+            INNER JOIN {cvterm} CVTO on CVTO.cvterm_id = CVTP.object_id
+            INNER JOIN {cvterm} CVTS on CVTS.cvterm_id = CVTP.subject_id
+            INNER JOIN {cvterm} CVTT on CVTT.cvterm_id = CVTP.type_id
+          WHERE CVTP.cv_id = :cv_id
+        ";
+    $args = [':cv_id' => $cv_id];
+    $rel_count = chado_query($sql, $args)->fetchField();
+    $expected = count($relationships);
+    $this->assertEquals($expected, $rel_count,
+      "There are an incorrect number of paths. There were $rel_count found but there should be $expected.");
   }
-
-
-
+  
   /**
-   * Test OBO has a xref.  check its inserted properly.
+   * Tests that the EBI Lookup is properly working.
+   * 
+   * The term CHEBI:132502 should have been loaded via EBI.
+   * 
    * @group obo
-   * @group wip
+   * @dataProvider testLocalOBO
    */
-  public function test_dbxref_loaded(){
-    //node11 has a synonym:"crazy node" EXACT []
-
-
-    $name = 'path_test_mini';
-    $path = __DIR__ . '/../example_files/cvtermpath_test.obo';
-    $this->load_obo($name, $path);
-
-    $cv_name = 'cvtermpath_test';
-
-    $query = db_select('chado.cvterm_dbxref', 't');
-    $query->join('chado.cvterm', 'cvt', 't.cvterm_id = cvt.cvterm_id');
-    $query->join('chado.dbxref', 'dbx', 'dbx.dbxref_id = t.dbxref_id');
-    $query->fields('dbx', ['accession']);
-    $query->condition('cvt.name', 'node11');
-
-    $result = $query->execute()->fetchField();
-
-    $this->assertNotFalse($result);
-
-    $this->assertEquals("0043226", $result);
-
+  public function testEBILookup($cv_id, $db_id) {
+    $sql = "
+       SELECT CVT.cvterm_id
+       FROM  {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE DB.name = 'CHEBI' and DBX.accession = '132502'
+    ";
+    $cvterm_id = chado_query($sql)->fetchField();
+    $this->assertNotFalse($cvterm_id,
+      "The term, CHEBI:132502, is not present the EBI OLS lookup must not have succeeded.");
   }
-
+  
   /**
-   * ensure that new CV's aren't accidentally created when term names have
-   * colons in them.
+   * Tests when changes are made between OBO loads.
+   *
+   * Sometimes an ontology can change the names of it's terms, or set some
+   * as obsolete, etc. We need to makes sure that when changes are made and
+   * the OBO is reloaded that the terms are properly update.
    *
    * @group obo
-   * @ticket 525
+   * @dataProvider testLocalOBO
    */
-  public function test_PTO_loads_colon_issue() {
-
-    $name = 'core_test_PTO_mini';
-    $path = __DIR__ . '/../example_files/pto_colon.obo';
-
-    $this->load_obo($name, $path);
-
-    $exists = db_select('chado.cv', 'c')
-      ->fields('c', ['cv_id'])
-      ->condition('name', 'core_test_PTO_mini')
-      ->execute()
-      ->fetchField();
-    $this->assertNotFalse($exists);
-
-    //hte colon splitting issue: a new CV will created named fatty acid 18
-    $exists = db_select('chado.cv', 'c')
-      ->fields('c', ['cv_id'])
-      ->condition('name', 'fatty acid 18')
-      ->execute()
-      ->fetchField();
-    $this->assertFalse($exists);
-
+  public function testOBOChanges($cv_id, $db_id) {
+    $name = 'tripal_obo_test_update';
+    $path = __DIR__ . '/../example_files/test.update.obo';
+    
+    $this->loadOBO($name, $path);
+    
+    // Did the name of term 13 change?
+    $sql = "
+      SELECT CVT.name
+      FROM {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE DB.name = 'TOT' and DBX.accession = '013'
+    ";
+    $name = chado_query($sql)->fetchField();
+    $this->assertEquals('New name 13.', $name,
+      "The name for node13 (TOT:013) failed to update to 'New name 13'.");
+    
+    // Node15 is new, and node02 got removed. Node15 now uses node02's name and
+    // has TOT:002 as an alt_id. So, node02 should be marked as obsolete
+    $sql = "
+      SELECT CVT.is_obsolete
+      FROM {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE DB.name = 'TOT' and DBX.accession = '002'
+    ";
+    $is_obsolete = chado_query($sql)->fetchField();
+    $this->assertEquals(1, $is_obsolete,
+      "The node02 (TOT:002) should be marked as obsolete after update.");
+    
+    // Node16 is new, and node08 is now obsolete. Node16 now uses node08's name,
+    // so, node08 should be marked as obsolete and have the word '(obsolete)'
+    // added to prevent future conflicts.
+    $sql = "
+      SELECT CVT.name
+      FROM {cvterm} CVT
+         INNER JOIN {dbxref} DBX on DBX.dbxref_id = CVT.dbxref_id
+         INNER JOIN {db} DB on DB.db_id = DBX.db_id
+       WHERE DB.name = 'TOT' and DBX.accession = '008'
+    ";
+    $name = chado_query($sql)->fetchField();
+    $this->assertEquals("node08 (obsolete)", $name,
+      "The node08 (TOT:008) should be marked as obsolete after update.");
   }
-
-
 }

+ 1 - 1
tripal_chado/api/modules/tripal_chado.cv.api.inc

@@ -435,7 +435,7 @@ function chado_update_cvtermpath($cv_id, $job = NULL) {
         INNER JOIN {cvterm} CVTO on CVTO.cvterm_id = CVTR.object_id
         INNER JOIN {cvterm} CVTS on CVTS.cvterm_id = CVTR.subject_id
       WHERE CVTO.cv_id = :cv_id 
-      ORDER BY CVTR.object_id, CVTR.subject_id
+      ORDER BY CVTO.name, CVTS.name
     ";
     $rels = chado_query($sql, [':cv_id' => $cv_id]);
     $total_items;

+ 2 - 1
tripal_chado/includes/TripalImporter/OBOImporter.inc

@@ -1326,13 +1326,14 @@ class OBOImporter extends TripalImporter {
       if (!$check_stanza) {
         $new_name = $check_cvterm->getValue('name') . ' (' . $check_accession . ')';
         $check_cvterm->setValue('name', $new_name);
+        $check_cvterm->setValue('is_obsolete', '1');
         $check_cvterm->update();
         return TRUE;
       }
       // Case 2:  The conflicting term is in the OBO file (ie. has a stanza) and
       // is obsolete and this one is not. Fix it by adding an (obsolete) suffix 
       // to the name to avoid the conflict.
-      else if ($check_stanza['is_obsolete'] == 'true' and $stanza['is_obsolete'] != 'true') {
+      else if ($check_stanza['is_obsolete'][0] == 'true' and $stanza['is_obsolete'][0] != 'true') {
         $new_name = $check_cvterm->getValue('name') . ' (obsolete)';
         $check_cvterm->setValue('name', $new_name);
         $check_cvterm->update();