org.openmrs.module.sync.SyncConceptTest.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.sync.SyncConceptTest.java

Source

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.sync;

import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.junit.Assert;
import org.junit.Test;
import org.openmrs.Concept;
import org.openmrs.ConceptAnswer;
import org.openmrs.ConceptDescription;
import org.openmrs.ConceptName;
import org.openmrs.ConceptNameTag;
import org.openmrs.ConceptNumeric;
import org.openmrs.ConceptSet;
import org.openmrs.ConceptWord;
import org.openmrs.api.ConceptNameType;
import org.openmrs.api.ConceptService;
import org.openmrs.api.context.Context;
import org.springframework.test.annotation.NotTransactional;

/**
 * Tests sending Concepts over the wire
 */
public class SyncConceptTest extends SyncBaseTest {

    @Override
    public String getInitialDataset() {
        try {
            return "org/openmrs/module/sync/include/" + new TestUtil().getTestDatasetFilename("syncCreateTest");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    @NotTransactional
    public void shouldSaveConceptDescriptionsWithConcept() throws Exception {
        runSyncTest(new SyncTestHelper() {

            String conceptName = "A concept";

            public void runOnChild() throws Exception {
                ConceptService cs = Context.getConceptService();

                Concept concept = new Concept();
                concept.setDatatype(cs.getConceptDatatypeByName("Coded"));
                concept.setConceptClass(cs.getConceptClassByName("Question"));
                concept.addName(new ConceptName(conceptName, Context.getLocale()));
                concept.addDescription(new ConceptDescription("asdf", Context.getLocale()));
                cs.saveConcept(concept);
            }

            public void runOnParent() throws Exception {
                ConceptService cs = Context.getConceptService();

                log.info("The current locale: " + Context.getLocale());

                Concept c = cs.getConceptByName(conceptName);
                assertNotNull("Failed to create the concept", c);

                log.info("descriptions: " + c.getDescriptions());
                assertTrue("Failed to transfer descriptions", c.getDescriptions().size() > 0);
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldSaveConceptCoded() throws Exception {
        runSyncTest(new SyncTestHelper() {

            public void runOnChild() {
                ConceptService cs = Context.getConceptService();

                Concept coded = new Concept();
                coded.setDatatype(cs.getConceptDatatypeByName("Coded"));
                coded.setConceptClass(cs.getConceptClassByName("Question"));
                coded.setSet(false);
                ConceptName name = new ConceptName("CODED", Context.getLocale());
                ConceptNameTag tag = new ConceptNameTag("default", "The default name");
                tag.setConceptNameTagId(1);
                name.addTag(tag);
                coded.addName(name);
                coded.addDescription(new ConceptDescription("asdf", Context.getLocale()));
                coded.addAnswer(new ConceptAnswer(cs.getConceptByName("OTHER NON-CODED")));
                coded.addAnswer(new ConceptAnswer(cs.getConceptByName("NONE")));
                cs.saveConcept(coded);
            }

            public void runOnParent() {
                Context.clearSession();

                ConceptService cs = Context.getConceptService();

                log.info("The current locale: " + Context.getLocale());

                Concept c = cs.getConceptByName("CODED");
                assertNotNull("Failed to create CODED concept", c);

                log.info("names: " + c.getNames(true));
                try {
                    Field field = Concept.class.getDeclaredField("names");
                    field.setAccessible(true);
                    log.info("concept names list via reflection: " + field.get(c));
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    log.error("Error generated", e);
                } catch (SecurityException e) {
                    // TODO Auto-generated catch block
                    log.error("Error generated", e);
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    log.error("Error generated", e);
                } catch (NoSuchFieldException e) {
                    // TODO Auto-generated catch block
                    log.error("Error generated", e);
                }
                assertTrue("Failed to transfer names", c.getNames(true).size() > 0);
                assertEquals(c.getConceptClass().getConceptClassId(),
                        cs.getConceptClassByName("Question").getConceptClassId());
                assertEquals(c.getDatatype().getConceptDatatypeId(),
                        cs.getConceptDatatypeByName("Coded").getConceptDatatypeId());

                Collection<ConceptAnswer> answers = c.getAnswers();
                assertEquals(2, answers.size());

            }
        });
    }

    @Test
    @NotTransactional
    public void shouldSaveConceptNumeric() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs;

            public void runOnChild() {
                cs = Context.getConceptService();
                ConceptNumeric cn = new ConceptNumeric();
                cn.addName(new ConceptName("SOMETHING NUMERIC", Context.getLocale()));
                cn.setDatatype(cs.getConceptDatatypeByName("Numeric"));
                cn.setConceptClass(cs.getConceptClassByName("Question"));
                cn.setSet(false);
                cn.setPrecise(true);
                cn.setLowAbsolute(0d);
                cn.setHiCritical(100d);
                cs.saveConcept(cn);
            }

            public void runOnParent() {
                Context.clearSession();

                Concept c = cs.getConceptByName("SOMETHING NUMERIC");
                assertNotNull("Failed to create numeric", c);
                log.info("1: " + c);
                assertNotNull("No names got transferred", c.getNames());
                assertTrue("No names got transferred", c.getNames().size() > 0);
                assertEquals(c.getName().getName(), "SOMETHING NUMERIC");
                ConceptNumeric cn = cs.getConceptNumeric(c.getConceptId());
                assertEquals("Concept numeric absolute low values do not match", (Double) 0d, cn.getLowAbsolute());
                assertEquals("Concept nuermic high critical values do not match", (Double) 100d,
                        cn.getHiCritical());
                assertEquals("Concept numeric datatypes does not match", "Numeric", cn.getDatatype().getName());
                assertEquals("Concept numeric classes does not match", "Question", cn.getConceptClass().getName());

            }
        });
    }

    @Test
    @NotTransactional
    public void shouldSaveConceptSet() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs;

            private int conceptNumericId = 99997;

            private int conceptCodedId = 99998;

            private int conceptSetId = 99999;

            public void runOnChild() {
                cs = Context.getConceptService();

                ConceptNumeric cn = new ConceptNumeric();
                cn.setConceptId(conceptNumericId);
                cn.addName(new ConceptName("SOMETHING NUMERIC", Context.getLocale()));
                cn.setDatatype(cs.getConceptDatatypeByName("Numeric"));
                cn.setConceptClass(cs.getConceptClassByName("Question"));
                cn.setSet(false);
                cn.setPrecise(true);
                cn.setLowAbsolute(0d);
                cn.setHiCritical(100d);
                cs.saveConcept(cn);

                Concept coded = new Concept();
                coded.setConceptId(conceptCodedId);
                coded.addName(new ConceptName("SOMETHING CODED", Context.getLocale()));
                coded.setDatatype(cs.getConceptDatatypeByName("Coded"));
                coded.setConceptClass(cs.getConceptClassByName("Question"));
                coded.setSet(false);

                Concept other = cs.getConceptByName("OTHER NON-CODED");
                assertNotNull("Failed to get concept OTHER NON-CODED", other);

                Concept none = cs.getConceptByName("NONE");
                assertNotNull("Failed to get concept NONE", none);

                coded.addAnswer(new ConceptAnswer(other));
                coded.addAnswer(new ConceptAnswer(none));
                coded.addAnswer(new ConceptAnswer(cn));
                cs.saveConcept(coded);

                //ConceptSet conceptSet = new ConceptSet();

                Concept set = new Concept(conceptSetId);

                log.info("Locale: " + Context.getLocale());

                set.addName(new ConceptName("A CONCEPT SET", Context.getLocale()));
                set.setDatatype(cs.getConceptDatatypeByName("N/A"));
                set.setConceptClass(cs.getConceptClassByName("ConvSet"));
                set.setSet(true);
                Set<ConceptSet> cset = new HashSet<ConceptSet>();
                cset.add(new ConceptSet(coded, 1d));
                cset.add(new ConceptSet(cn, 2d));
                set.setConceptSets(cset);
                cs.saveConcept(set);
            }

            public void runOnParent() {
                Context.clearSession();

                Concept c = cs.getConceptByName("SOMETHING NUMERIC");
                assertNotNull("Failed to create numeric", c);

                assertNotNull("Failed to find a name", c.getName());
                assertEquals("Concept names do not match", "SOMETHING NUMERIC", c.getName().getName());

                ConceptNumeric cn = cs.getConceptNumeric(c.getConceptId());
                assertEquals("Concept numeric absolute low values do not match", (Double) 0d, cn.getLowAbsolute());
                assertEquals("Concept numeric critical high values do not match", (Double) 100d,
                        cn.getHiCritical());
                assertEquals("Concept numeric datatypes do not match", "Numeric", cn.getDatatype().getName());
                assertEquals("Concept numeric classes do not match", "Question", cn.getConceptClass().getName());

                // Test the coded concept          
                Concept conceptCoded = cs.getConceptByName("SOMETHING CODED");
                assertNotNull("Failed to save coded concept - Could not retrieve concept by name", conceptCoded);

                Set<String> answers = new HashSet<String>();
                for (ConceptAnswer a : conceptCoded.getAnswers()) {
                    answers.add(a.getAnswerConcept().getName().getName());
                }
                Assert.assertTrue(answers.contains("SOMETHING NUMERIC"));
                Assert.assertTrue(answers.contains("OTHER NON-CODED"));
                Assert.assertTrue(answers.contains("NONE"));

                // Test the concept set 
                Concept conceptSet = cs.getConceptByName("A CONCEPT SET");
                assertNotNull("Failed to create coded concept - Could not retrieve code concept by name",
                        conceptSet);

                assertEquals("Failed to create concept set - Concept set should have two elements",
                        conceptSet.getConceptSets().size(), 2);

            }
        });
    }

    @Test
    @NotTransactional
    public void shouldAddExistingConceptToExistingSet() throws Exception {

        runSyncTest(new SyncTestHelper() {

            ConceptService cs;

            public void runOnChild() {
                cs = Context.getConceptService();
                Concept maritalStatus = cs.getConcept(15);
                Concept singleConcept = cs.getConcept(14);
                maritalStatus.addSetMember(singleConcept);
                cs.saveConcept(maritalStatus);
            }

            public void runOnParent() {
                Context.clearSession();
                cs = Context.getConceptService();
                Concept maritalStatus = cs.getConcept(15);
                List<Concept> statuses = maritalStatus.getSetMembers();
                Assert.assertEquals(2, statuses.size());
                Assert.assertEquals(14, statuses.get(1).getConceptId().intValue());
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldEditConcepts() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs;

            int numAnswersBefore;

            public void runOnChild() {
                cs = Context.getConceptService();
                Concept wt = cs.getConceptByName("WEIGHT");
                ConceptNumeric weight = cs.getConceptNumeric(wt.getConceptId());
                weight.setHiCritical(200d);
                cs.saveConcept(weight);

                Concept coded = cs.getConceptByName("CAUSE OF DEATH");
                assertNotNull(coded);
                Concept malaria = new Concept(99999);
                malaria.addName(new ConceptName("MALARIA", Context.getLocale()));
                malaria.setDatatype(cs.getConceptDatatypeByName("N/A"));
                malaria.setConceptClass(cs.getConceptClassByName("Diagnosis"));
                cs.saveConcept(malaria);
                numAnswersBefore = coded.getAnswers().size();
                coded.addAnswer(new ConceptAnswer(malaria));
                cs.saveConcept(coded);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName("WEIGHT");
                ConceptNumeric weight = cs.getConceptNumeric(wt.getConceptId());
                assertEquals("Failed to change property on a numeric concept", (Double) 200d,
                        weight.getHiCritical());

                Concept malaria = cs.getConceptByName("MALARIA");
                assertNotNull("Implicit create of concept referenced in answer failed", malaria);

                Concept coded = cs.getConceptByName("CAUSE OF DEATH");
                assertEquals("Adding answer failed", numAnswersBefore + 1, coded.getAnswers().size());
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldAddNameToConcept() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            int numNamesBefore;

            public void runOnChild() {
                Concept wt = cs.getConceptByName("WEIGHT");
                numNamesBefore = wt.getNames().size();
                wt.addName(new ConceptName("POIDS", Locale.FRENCH));
                cs.saveConcept(wt);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName("WEIGHT");
                assertNotNull(wt);
                assertEquals("Should be one more name than before", numNamesBefore + 1, wt.getNames().size());
                assertEquals("Incorrect french name", "POIDS", wt.getName(Locale.FRENCH, true).getName());
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldAddDescriptionToConcept() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            int numDescriptionsBefore;

            public void runOnChild() {
                Concept wt = cs.getConceptByName("WEIGHT");
                numDescriptionsBefore = wt.getDescriptions().size();
                wt.addDescription(new ConceptDescription("Everyone tries to lose this", Locale.FRENCH));
                cs.saveConcept(wt);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName("WEIGHT");
                assertNotNull(wt);
                assertEquals("Should be one more description than before", numDescriptionsBefore + 1,
                        wt.getDescriptions().size());
                assertEquals("Incorrect french description", wt.getDescription(Locale.FRENCH).getDescription(),
                        "Everyone tries to lose this");
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldAddTagToConceptName() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            int numTagsBefore;

            public void runOnChild() {
                Concept wt = cs.getConceptByName("WEIGHT");
                ConceptName cn = wt.getName();
                numTagsBefore = cn.getTags().size();
                ConceptNameTag tag = cs.getConceptNameTagByName("default");
                cn.addTag(tag);
                cs.saveConcept(wt);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName("WEIGHT");
                assertNotNull(wt);
                ConceptName cn = wt.getName();
                assertEquals("Should be one more tag than before", numTagsBefore + 1, cn.getTags().size());
                assertEquals("tag not added", true, cn.hasTag("default"));
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldUpdateConceptWordsForNumericConcepts() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            public void runOnChild() {
                Concept wt = cs.getConceptByName("WEIGHT");
                wt.addName(new ConceptName("ASDF", Locale.UK));
                cs.saveConcept(wt);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName("WEIGHT");
                List<ConceptWord> words = cs.getConceptWords("ASDF", Locale.UK);
                boolean foundConcept = false;
                for (ConceptWord word : words) {
                    if (word.getConcept().equals(wt)) {
                        foundConcept = true;
                    }
                }

                assertTrue(foundConcept);
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldUpdateConceptWordsForNewConcepts() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            String conceptname = "THENEWCONCEPT";

            public void runOnChild() {
                Concept newConcept = new Concept();
                newConcept.addName(new ConceptName(conceptname, Context.getLocale()));
                cs.saveConcept(newConcept);
            }

            public void runOnParent() {
                Concept wt = cs.getConceptByName(conceptname);
                List<ConceptWord> words = cs.getConceptWords(conceptname, Context.getLocale());
                boolean foundConcept = false;
                for (ConceptWord word : words) {
                    if (word.getConcept().equals(wt)) {
                        foundConcept = true;
                    }
                }

                assertTrue("The new concept's name was not found in the concept words", foundConcept);
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldAddAndRemoveConceptAnswer() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs;

            public void runOnChild() {
                cs = Context.getConceptService();

                Concept coded = cs.getConcept(1);

                // remove the first answer
                coded.removeAnswer(coded.getAnswers().toArray(new ConceptAnswer[] {})[0]);

                // add a new answer
                Concept other = cs.getConceptByName("WEIGHT");
                assertNotNull("Failed to get concept WEIGHT", other);
                coded.addAnswer(new ConceptAnswer(other));

                cs.saveConcept(coded);
            }

            public void runOnParent() {
                Context.clearSession();

                Concept conceptCoded = cs.getConcept(1);

                Set<String> answers = new HashSet<String>();
                for (ConceptAnswer a : conceptCoded.getAnswers()) {
                    answers.add(a.getAnswerConcept().getName().getName());
                }
                Assert.assertTrue(answers.contains("WEIGHT")); // we added this as a new answer
                Assert.assertFalse(answers.contains("OTHER NON-CODED")); // we removed this
                Assert.assertTrue(answers.contains("NONE")); // was already on the concept

            }
        });
    }

    @Test
    @NotTransactional
    public void shouldTurnConceptIntoConceptNumericWithoutFrakkingUuids() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            Integer conceptId = 2;
            String oldUuid = null;

            public void runOnChild() {
                Concept concept = cs.getConcept(conceptId);
                oldUuid = concept.getUuid();
                ConceptNumeric cn = new ConceptNumeric(concept);
                cn.setHiAbsolute(10.0);
                cs.saveConcept(cn);
                Assert.assertEquals(conceptId, cn.getConceptId());
                //Assert.assertEquals(oldUuid, cn.getUuid());
                Assert.assertEquals(oldUuid, concept.getUuid());
            }

            public void runOnParent() {
                Concept originalConcept = cs.getConcept(conceptId);
                ConceptNumeric originalConceptByUuid = cs.getConceptNumericByUuid(oldUuid);
                Assert.assertNotNull("The numeric concept does not have the right uuid, something got frakked",
                        originalConceptByUuid);
                Assert.assertEquals(oldUuid, originalConcept.getUuid());
                Assert.assertEquals(conceptId, originalConceptByUuid.getConceptId());
                Assert.assertEquals(10.0, originalConceptByUuid.getHiAbsolute().doubleValue(), 0.001);
            }
        });
    }

    @Test
    @NotTransactional
    public void shouldSyncConceptNameIndexTerm() throws Exception {
        runSyncTest(new SyncTestHelper() {

            ConceptService cs = Context.getConceptService();

            public void runOnChild() {
                Concept married = cs.getConceptByName("MARRIED");
                Assert.assertEquals(1, married.getNames().size());

                ConceptName cn = new ConceptName();
                cn.setName("WEDDED");
                cn.setConcept(married);
                cn.setConceptNameType(ConceptNameType.INDEX_TERM);
                cn.setLocale(Locale.ENGLISH);
                cn.setLocalePreferred(false);
                married.addName(cn);
                cs.saveConcept(married);

                married = cs.getConceptByName("MARRIED");
                Assert.assertEquals(2, married.getNames().size());
            }

            public void runOnParent() {
                Concept married = cs.getConceptByName("MARRIED");
                Assert.assertEquals(2, married.getNames().size());
                for (ConceptName cn : married.getNames()) {
                    if (cn.getName().equals("WEDDED")) {
                        Assert.assertEquals(ConceptNameType.INDEX_TERM, cn.getConceptNameType());
                    }
                }
            }
        });
    }
}