Orthanc/OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp
2025-06-23 19:07:37 +05:30

274 lines
9.2 KiB
C++

/**
* Orthanc - A Lightweight, RESTful DICOM Store
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
* Department, University Hospital of Liege, Belgium
* Copyright (C) 2017-2023 Osimis S.A., Belgium
* Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
* Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "PrecompiledHeadersUnitTests.h"
#include <gtest/gtest.h>
#include "../../OrthancFramework/Sources/OrthancException.h"
#include "../Sources/Search/DatabaseLookup.h"
using namespace Orthanc;
TEST(DatabaseLookup, SingleConstraint)
{
{
ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal,
"HEL*LO", true, true), OrthancException);
ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal,
"HEL?LO", true, true), OrthancException);
ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal,
true, true), OrthancException);
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal, "HELLO", true, true);
ASSERT_TRUE(tag.IsMatch("HELLO"));
ASSERT_FALSE(tag.IsMatch("hello"));
ASSERT_TRUE(tag.IsCaseSensitive());
ASSERT_EQ(ConstraintType_Equal, tag.GetConstraintType());
DicomMap m;
ASSERT_FALSE(tag.IsMatch(m));
m.SetNullValue(DICOM_TAG_PATIENT_NAME);
ASSERT_FALSE(tag.IsMatch(m));
m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", true /* binary */);
ASSERT_FALSE(tag.IsMatch(m));
m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false /* string */);
ASSERT_TRUE(tag.IsMatch(m));
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal, "HELlo", false, true);
ASSERT_TRUE(tag.IsMatch("HELLO"));
ASSERT_TRUE(tag.IsMatch("hello"));
ASSERT_EQ("HELlo", tag.GetValue());
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Wildcard, "HE*L?O", true, true);
ASSERT_TRUE(tag.IsMatch("HELLO"));
ASSERT_TRUE(tag.IsMatch("HELLLLLO"));
ASSERT_TRUE(tag.IsMatch("HELxO"));
ASSERT_FALSE(tag.IsMatch("hello"));
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Wildcard, "HE*l?o", false, true);
ASSERT_TRUE(tag.IsMatch("HELLO"));
ASSERT_TRUE(tag.IsMatch("HELLLLLO"));
ASSERT_TRUE(tag.IsMatch("HELxO"));
ASSERT_TRUE(tag.IsMatch("hello"));
ASSERT_FALSE(tag.IsCaseSensitive());
ASSERT_EQ(ConstraintType_Wildcard, tag.GetConstraintType());
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_SmallerOrEqual, "123", true, true);
ASSERT_TRUE(tag.IsMatch("120"));
ASSERT_TRUE(tag.IsMatch("123"));
ASSERT_FALSE(tag.IsMatch("124"));
ASSERT_TRUE(tag.IsMandatory());
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_GreaterOrEqual, "123", true, false);
ASSERT_FALSE(tag.IsMatch("122"));
ASSERT_TRUE(tag.IsMatch("123"));
ASSERT_TRUE(tag.IsMatch("124"));
ASSERT_FALSE(tag.IsMandatory());
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_List, true, true);
ASSERT_FALSE(tag.IsMatch("CT"));
ASSERT_FALSE(tag.IsMatch("MR"));
tag.AddValue("CT");
ASSERT_TRUE(tag.IsMatch("CT"));
ASSERT_FALSE(tag.IsMatch("MR"));
tag.AddValue("MR");
ASSERT_TRUE(tag.IsMatch("CT"));
ASSERT_TRUE(tag.IsMatch("MR"));
ASSERT_FALSE(tag.IsMatch("ct"));
ASSERT_FALSE(tag.IsMatch("mr"));
ASSERT_THROW(tag.GetValue(), OrthancException);
ASSERT_EQ(2u, tag.GetValues().size());
}
{
DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_List, false, true);
tag.AddValue("ct");
tag.AddValue("mr");
ASSERT_TRUE(tag.IsMatch("CT"));
ASSERT_TRUE(tag.IsMatch("MR"));
ASSERT_TRUE(tag.IsMatch("ct"));
ASSERT_TRUE(tag.IsMatch("mr"));
}
}
TEST(DatabaseLookup, FromDicom)
{
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_ID, "HELLO", true, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(ConstraintType_Equal, lookup.GetConstraint(0).GetConstraintType());
ASSERT_EQ("HELLO", lookup.GetConstraint(0).GetValue());
ASSERT_TRUE(lookup.GetConstraint(0).IsCaseSensitive());
ASSERT_TRUE(lookup.HasTag(DICOM_TAG_PATIENT_ID));
ASSERT_FALSE(lookup.HasTag(DICOM_TAG_PATIENT_NAME));
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_ID, "HELLO", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
// This is *not* a PN VR => "false" above is *not* used
ASSERT_TRUE(lookup.GetConstraint(0).IsCaseSensitive());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_NAME, "HELLO", true, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_TRUE(lookup.GetConstraint(0).IsCaseSensitive());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_NAME, "HELLO", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
// This is a PN VR => "false" above is used
ASSERT_FALSE(lookup.GetConstraint(0).IsCaseSensitive());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_SERIES_DESCRIPTION, "2012-2016", false, true);
// This is not a data VR
ASSERT_EQ(ConstraintType_Equal, lookup.GetConstraint(0).GetConstraintType());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_BIRTH_DATE, "2012-2016", false, true);
// This is a data VR => range is effective
ASSERT_EQ(2u, lookup.GetConstraintsCount());
ASSERT_TRUE(lookup.GetConstraint(0).GetConstraintType() != lookup.GetConstraint(1).GetConstraintType());
for (size_t i = 0; i < 2; i++)
{
ASSERT_TRUE(lookup.GetConstraint(i).GetConstraintType() == ConstraintType_SmallerOrEqual ||
lookup.GetConstraint(i).GetConstraintType() == ConstraintType_GreaterOrEqual);
}
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_BIRTH_DATE, "2012-", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(ConstraintType_GreaterOrEqual, lookup.GetConstraint(0).GetConstraintType());
ASSERT_EQ("2012", lookup.GetConstraint(0).GetValue());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_BIRTH_DATE, "-2016", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(DICOM_TAG_PATIENT_BIRTH_DATE, lookup.GetConstraint(0).GetTag());
ASSERT_EQ(ConstraintType_SmallerOrEqual, lookup.GetConstraint(0).GetConstraintType());
ASSERT_EQ("2016", lookup.GetConstraint(0).GetValue());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_MODALITIES_IN_STUDY, "CT\\MR", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(DICOM_TAG_MODALITIES_IN_STUDY, lookup.GetConstraint(0).GetTag());
ASSERT_EQ(ConstraintType_List, lookup.GetConstraint(0).GetConstraintType());
const std::set<std::string>& values = lookup.GetConstraint(0).GetValues();
ASSERT_EQ(2u, values.size());
ASSERT_TRUE(values.find("CT") != values.end());
ASSERT_TRUE(values.find("MR") != values.end());
ASSERT_TRUE(values.find("nope") == values.end());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_STUDY_DESCRIPTION, "CT\\MR", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(DICOM_TAG_STUDY_DESCRIPTION, lookup.GetConstraint(0).GetTag());
ASSERT_EQ(ConstraintType_List, lookup.GetConstraint(0).GetConstraintType());
const std::set<std::string>& values = lookup.GetConstraint(0).GetValues();
ASSERT_EQ(2u, values.size());
ASSERT_TRUE(values.find("CT") != values.end());
ASSERT_TRUE(values.find("MR") != values.end());
ASSERT_TRUE(values.find("nope") == values.end());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_STUDY_DESCRIPTION, "HE*O", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(ConstraintType_Wildcard, lookup.GetConstraint(0).GetConstraintType());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_STUDY_DESCRIPTION, "HE?O", false, true);
ASSERT_EQ(1u, lookup.GetConstraintsCount());
ASSERT_EQ(ConstraintType_Wildcard, lookup.GetConstraint(0).GetConstraintType());
}
{
DatabaseLookup lookup;
lookup.AddDicomConstraint(DICOM_TAG_RELATED_FRAME_OF_REFERENCE_UID, "TEST", false, true);
lookup.AddDicomConstraint(DICOM_TAG_PATIENT_NAME, "TEST2", false, false);
ASSERT_TRUE(lookup.GetConstraint(0).IsMandatory());
ASSERT_FALSE(lookup.GetConstraint(1).IsMandatory());
}
}