diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..44e8830 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,44 @@ +name: "CodeQL" + +on: + push: + branches: [master] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + schedule: + - cron: '0 18 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: ['java'] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..88ae06a --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,37 @@ +# Build the project and run unit tests + +name: integration + +on: [ push, pull_request ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '21' + - name: Cache Gradle packages + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Build and analyze + env: + SEER_API_KEY: ${{ secrets.SEER_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + chmod +x gradlew + ./gradlew --continue build sonar diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..8d2ef4a --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +# Publish to Maven Central + +name: publish + +on: + repository_dispatch: + types: manual-publish + release: + types: [created] + +jobs: + publish: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '21' + - name: Publish to Maven Central (Portal) + run: | + chmod +x gradlew + ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} diff --git a/.gitignore b/.gitignore index 190c29f..47bd85e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target /build +/out /dist /classes /.gradle diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f1d3876..0000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: java - -jdk: -- oraclejdk8 - -before_install: -- chmod +x gradlew - -env: - global: - - secure: ahfNxDTQyt3G0nI/XQZHTUQUzlv4z0FLk8OycmxbK2HzX29d/XyyF0EJKDJ4IqjsIR3++i/DP9j6BSW4Rrl7WpuvkKjArwIVXgs0vHHsII0CKPMi3D+7KxreWutONGNuxfJoW17vl9Sp/2lwGP7s0asFGdt/C3F6sj23l/dobiQ= - -notifications: - email: - - mayc@imsweb.com - - depryf@imsweb.com - diff --git a/README.md b/README.md index e73167c..16a88c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # seerapi-client-java -[![Build Status](https://travis-ci.org/imsweb/seerapi-client-java.svg?branch=master)](https://travis-ci.org/imsweb/seerapi-client-java) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=imsweb_seerapi-client-java&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=imsweb_seerapi-client-java) +[![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg)](https://github.com/imsweb/seerapi-client-java/actions) +[![Maven Central](https://img.shields.io/maven-central/v/com.imsweb/seerapi-client-java.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and makes them easy to incorporate into Java applications. @@ -29,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.5 + 5.9 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.5' +compile 'com.imsweb:seerapi-client-java:5.9' ``` ## Usage @@ -131,15 +132,17 @@ A searchable database for coding oncology drug and regimen treatment categories api.rx().getById("latest", "53c44b01102c1290262dc8b2").execute().body() ``` -### SEER Incidence Site Recode (rest/recode) +### Site Recode (rest/recode) -The values of SEER site recode variables are based on the primary site and histology data fields submitted to SEER by the -registries. The site recode variables define the major cancer site/histology groups that are commonly used in the reporting of -cancer incidence data. For example, there is a section of the SEER Cancer Statistics Review for each major site corresponding to -groupings in a site recode variable. The site recode variables are added to SEER databases as a convenience for researchers. +The API supports three algorithms for recoding site: SEER site recode ("seer"), International Classification of Childhood Cancer Site Recode ("iccc"), +and Adolescents and Young Adults Site Recode ("aya"). The values of SEER site recode variables are based on the primary site, histology and +behavior data fields submitted to SEER by the registries. The site recode variables define the major cancer site/histology groups that +are commonly used in the reporting of cancer incidence data. For example, there is a section of the SEER Cancer Statistics Review for +each major site corresponding to groupings in a site recode variable. The site recode variables are added to SEER databases as a +convenience for researchers. ```java -api.siteRecode().siteGroup("C619", "8000").execute().body() +api.siteRecode().siteGroup("seer", "C619", "8000", null).execute().body() ``` ### Site-specific Surgery Codes (rest/surgery) @@ -150,6 +153,14 @@ The site-specific surgery tables available on the SEER website. api.surgery().tables().execute().body() ``` +### HCPCS + +Healthcare Common Procedure Coding Systems (HCPCS) nomenclatures. The information is maintained through [CanMED](https://seer.cancer.gov/oncologytoolbox). + +```java +api.hcpcs().getProcedure("S0087").execute().body(); +``` + ### Staging Cancer staging algorithms. Currently supports Collaborative Stage which is a unified data collection system designed to provide a @@ -157,11 +168,11 @@ common data set to meet the needs of all three staging systems (TNM, SEER EOD, a improve data quality by standardizing rules for timing, clinical and pathologic assessments, and compatibility across all of the systems for all cancer sites. -``` +```java api.staging().schemaById("cs", "02.05.50", "brain").execute().body() ``` For a complete description of all available API inputs and outputs, see the SEER*API -[Documentation](https://api.seer.cancer.gov/api.do) page. +[Documentation](https://api.seer.cancer.gov/docs) page. [1]: http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.imsweb&a=seerapi-client-java&v=LATEST diff --git a/build.gradle b/build.gradle index e30142f..e9c7110 100644 --- a/build.gradle +++ b/build.gradle @@ -1,26 +1,31 @@ -import org.gradle.internal.jvm.Jvm +import com.vanniktech.maven.publish.JavaLibrary +import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.SonatypeHost plugins { - id 'java' + id 'java-library' id 'checkstyle' - id 'findbugs' - id 'com.bmuschko.nexus' version '2.3.1' - id "io.codearte.nexus-staging" version "0.8.0" // logs into Sonotype OSS and does a "Close" and "Release" - id 'net.ossindex.audit' version '0.1.1' + id 'jacoco' + id "com.github.spotbugs" version "6.1.11" + id 'com.adarshr.test-logger' version '4.0.0' + id "com.github.ben-manes.versions" version "0.52.0" + id 'org.sonatype.gradle.plugins.scan' version '3.1.1' + id "org.sonarqube" version "6.2.0.5505" + id 'com.vanniktech.maven.publish' version '0.31.0' } group = 'com.imsweb' -version = '3.5' +version = '5.9' description = 'Java client library for SEER*API' -println "Starting build using ${Jvm.current()}" - -// UTF-8 for all compilation tasks -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + options.compilerArgs << "-Werror" << "-Xlint:-options" +} -// fail the build if there are compiler warnings -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:all" << "-Xlint:-processing" << "-Xlint:-serial" << "-Werror" +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } repositories { @@ -28,78 +33,130 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.2.0' - compile 'com.squareup.retrofit2:converter-jackson:2.1.0' + spotbugs 'com.github.spotbugs:spotbugs:4.9.3' + + api 'com.squareup.retrofit2:retrofit:2.11.0' + api 'com.squareup.retrofit2:converter-jackson:2.11.0' + api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.1' + + // retrofit will not update these dependencies to fix vulnerabilities + api 'com.squareup.okhttp3:okhttp:4.12.0' + api 'com.squareup.okio:okio:3.11.0' - testCompile 'junit:junit:4.11' + testImplementation platform('org.junit:junit-bom:5.12.2') + testImplementation 'org.junit.jupiter:junit-jupiter-api' + testImplementation 'org.junit.jupiter:junit-jupiter-params' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.12.2' + + testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } jar { // specify the archive name; otherwise the version is appended to the war file - archiveName = 'seerapi-java.jar' + archiveFileName = 'seerapi-java.jar' manifest { attributes('Implementation-Title': 'SEER*API Java Client', - 'Implementation-Version': version, + 'Implementation-Version': archiveVersion, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", 'Built-By': System.getProperty('user.name'), 'Built-Date': new Date(), 'Built-JDK': System.getProperty('java.version'), + 'Automatic-Module-Name': 'com.imsweb.seerapi.client' ) } } -// checkstyle plugin settings +tasks.withType(Javadoc).configureEach { + failOnError false + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') +} + +javadoc { + if (JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} + +test { + useJUnitPlatform() +} + +test.finalizedBy jacocoTestReport + +jacocoTestReport { + reports { + xml.required = true + } +} + checkstyle { - ignoreFailures = true + toolVersion = '8.29' configFile = file("config/checkstyle/checkstyle.xml") } -// findbugs plugin settings -findbugs { - ignoreFailures = true - effort = 'max' - excludeFilter = file("config/findbugs/findbugs-exclude.xml") +spotbugs { + excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } -// Gradle wrapper, this allows to build the project without having to install Gradle! -task wrapper(type: Wrapper) { - gradleVersion = '4.0' +sonarqube { + properties { + property "sonar.projectKey", "imsweb_seerapi-client-java" + property "sonar.organization", "imsweb" + property "sonar.host.url", "https://sonarcloud.io" + } } -modifyPom { - project { - name 'SEER*API Java Client' - description 'API mapping for SEER*API in Java' - url 'https://github.com/imsweb/seerapi-client-java' - inceptionYear '2014' +ossIndexAudit { + outputFormat = 'DEPENDENCY_GRAPH' + printBanner = false +} - scm { - url 'https://github.com/imsweb/seerapi-client-java' - connection 'scm:https://github.com/imsweb/seerapi-client-java.git' - developerConnection 'scm:git@github.com:imsweb/seerapi-client-java.git' - } +mavenPublishing { + configure(new JavaLibrary(new JavadocJar.Javadoc(), true)) + + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, true) + signAllPublications() + + pom { + name = 'SEER*API Java Client' + description = 'API mapping for SEER*API in Java' + url = 'https://github.com/imsweb/seerapi-client-java' licenses { license { - name 'The MIT License (MIT)' - url 'http://www.opensource.org/licenses/mit-license.php' - distribution 'repo' + name = 'The MIT License (MIT)' + url = 'http://www.opensource.org/licenses/mit-license.php' } } developers { developer { - id 'ctmay4' - name 'Chuck May' - email 'mayc@imsweb.com' + id = 'ctmay4' + name = 'Chuck May' + email = 'mayc@imsweb.com' } developer { - id 'depryf' - name 'Fabian Depry' - email 'depryf@imsweb.com' + id = 'depryf' + name = 'Fabian Depry' + email = 'depryf@imsweb.com' } } + + scm { + url = 'https://github.com/imsweb/seerapi-client-java' + connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' + developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' + } } } + +wrapper { + gradleVersion = '8.14' + distributionType = Wrapper.DistributionType.ALL +} diff --git a/config/checkstyle/checkstyle-exclude.xml b/config/checkstyle/checkstyle-exclude.xml deleted file mode 100644 index 9d941ec..0000000 --- a/config/checkstyle/checkstyle-exclude.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index a58e86b..6aaf4c2 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -1,169 +1,160 @@ - - + - - - + + - + - + - + - + - - - + + + - + - + - + - + - + - + - - - + + + - + - - + + - - - + + + - + - - + + - - + + - + - - + + - + - + - + - + - + - + - - - + + + - + - - - + + + - - + + - - + + - + - + - + - + - + - - + + - + - - - + + + - + - - + + - - + + - - + + - + - - + + - + - + - + - + - + - + - - - - - + diff --git a/config/findbugs/findbugs-exclude.xml b/config/spotbugs/spotbugs-exclude.xml similarity index 95% rename from config/findbugs/findbugs-exclude.xml rename to config/spotbugs/spotbugs-exclude.xml index a9f5d85..eee175d 100644 --- a/config/findbugs/findbugs-exclude.xml +++ b/config/spotbugs/spotbugs-exclude.xml @@ -36,6 +36,10 @@ + + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 60786f8..1b33c55 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44c1e4a..6514f91 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Fri Jun 16 16:42:51 EDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip diff --git a/gradlew b/gradlew index cccdd3d..23d15a9 100644 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f955316..db3a6ac 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,22 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,25 +27,29 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -35,48 +57,36 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java index a5f60f2..35476e4 100644 --- a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java +++ b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java @@ -5,26 +5,32 @@ import java.io.IOException; +import org.jetbrains.annotations.NotNull; + import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.Interceptor; import okhttp3.Response; +import okhttp3.ResponseBody; /** * Interceptor to catch all non-200 responses and convert them to exceptions. */ public class ErrorInterceptor implements Interceptor { + @NotNull @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); if (response.code() != 200) { - // convert body to error response ErrorResponse error = null; - if (response.body() != null) { + + // convert body to error response + ResponseBody body = response.body(); + if (body != null) { try { - error = new ObjectMapper().readValue(response.body().byteStream(), ErrorResponse.class); + error = new ObjectMapper().readValue(body.byteStream(), ErrorResponse.class); } catch (IOException e) { // sometimes the error message is not right format (like for 404 errors) diff --git a/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java b/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java index 68c6bf7..8c38e17 100644 --- a/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java +++ b/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java @@ -4,30 +4,54 @@ public class ErrorResponse { - @JsonProperty("code") - protected Integer _id; + @JsonProperty("timestamp") + private String _timestamp; + @JsonProperty("status") + private Integer _status; + @JsonProperty("error") + private String _error; @JsonProperty("message") - protected String _message; + private String _message; + @JsonProperty("path") + private String _path; - /** - * Default constructor - */ - public ErrorResponse() { + public String getTimestamp() { + return _timestamp; } - /** - * Return the error identifier - * @return an error identifier - */ - public Integer getId() { - return _id; + public void setTimestamp(String timestamp) { + _timestamp = timestamp; + } + + public Integer getStatus() { + return _status; + } + + public void setStatus(Integer status) { + _status = status; + } + + public String getError() { + return _error; + } + + public void setError(String error) { + _error = error; } - /** - * Return the error message - * @return an error message - */ public String getMessage() { return _message; } + + public void setMessage(String message) { + _message = message; + } + + public String getPath() { + return _path; + } + + public void setPath(String path) { + _path = path; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/SeerApi.java b/src/main/java/com/imsweb/seerapi/client/SeerApi.java index bcbfb91..45712a1 100644 --- a/src/main/java/com/imsweb/seerapi/client/SeerApi.java +++ b/src/main/java/com/imsweb/seerapi/client/SeerApi.java @@ -11,10 +11,11 @@ import java.util.Properties; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -23,6 +24,7 @@ import com.imsweb.seerapi.client.disease.DiseaseService; import com.imsweb.seerapi.client.glossary.GlossaryService; +import com.imsweb.seerapi.client.hcpcs.HcpcsService; import com.imsweb.seerapi.client.mph.MphService; import com.imsweb.seerapi.client.naaccr.NaaccrService; import com.imsweb.seerapi.client.ndc.NdcService; @@ -36,15 +38,16 @@ */ public final class SeerApi { - private DiseaseService _diseaseService; - private GlossaryService _glossaryService; - private MphService _mphService; - private NaaccrService _naaccrService; - private NdcService _ndcService; - private RxService _rxService; - private SiteRecodeService _siteRecodeService; - private StagingService _stagingService; - private SurgeryService _surgeryService; + private final DiseaseService _diseaseService; + private final GlossaryService _glossaryService; + private final MphService _mphService; + private final NaaccrService _naaccrService; + private final NdcService _ndcService; + private final RxService _rxService; + private final SiteRecodeService _siteRecodeService; + private final StagingService _stagingService; + private final SurgeryService _surgeryService; + private final HcpcsService _hcpcsService; /** * Creates a client API root object @@ -87,19 +90,18 @@ private SeerApi(String baseUrl, final String apiKey) { _siteRecodeService = retrofit.create(SiteRecodeService.class); _stagingService = retrofit.create(StagingService.class); _surgeryService = retrofit.create(SurgeryService.class); + _hcpcsService = retrofit.create(HcpcsService.class); } /** * Return the internal ObjectMapper - * @return + * @return an Objectmapper */ static ObjectMapper getMapper() { ObjectMapper mapper = new ObjectMapper(); // do not write null values - mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.setSerializationInclusion(Include.NON_NULL); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); @@ -109,6 +111,8 @@ static ObjectMapper getMapper() { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); mapper.setDateFormat(dateFormat); + mapper.registerModule(new JavaTimeModule()); + return mapper; } @@ -184,6 +188,14 @@ public SurgeryService surgery() { return _surgeryService; } + /** + * Return the HCPCS service + * @return an interface to all the HCPCS APIs + */ + public HcpcsService hcpcs() { + return _hcpcsService; + } + /** * Class to build a connection to SeerApi */ @@ -201,31 +213,20 @@ public static class Builder { /** * Return a list of user properties from the local .seerapi file - * @return + * @return Properties object */ private Properties getProperties() { Properties props = new Properties(); File config = new File(System.getProperty("user.home"), ".seerapi"); if (config.exists()) { - FileInputStream in = null; - try { - in = new FileInputStream(config); + try (FileInputStream in = new FileInputStream(config)) { props.load(in); } catch (IOException e) { // error reading } - finally { - try { - if (in != null) - in.close(); - } - catch (IOException e) { - // do nothing if error closing stream - } - } } return props; diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java b/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java index 1f0b25c..8e3e408 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java @@ -9,12 +9,6 @@ public class DateRange { @JsonProperty("end") protected String _endDate; - /** - * Default constructor - */ - public DateRange() { - } - public String getStartDate() { return _startDate; } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java b/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java index 7873f65..0a2c52b 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java @@ -7,12 +7,6 @@ public class DateRangeString extends DateRange { @JsonProperty("value") protected String _value; - /** - * Default constructor - */ - public DateRangeString() { - } - public String getValue() { return _value; } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java index f3e8ef8..e478827 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java @@ -6,112 +6,117 @@ import com.imsweb.seerapi.client.publishable.Publishable; +@SuppressWarnings("WeakerAccess") public class Disease extends Publishable { @JsonProperty("history") - protected List _history; + private List _history; /** * Identifying information */ @JsonProperty("icdO3_morphology") - protected String _icdO3Morphology; + private String _icdO3Morphology; @JsonProperty("primary_site") - protected List _primarySite; + private List _primarySite; @JsonProperty("primary_site_text") - protected String _primarySiteText; + private String _primarySiteText; @JsonProperty("site_category") - protected String _siteCategory; + private String _siteCategory; @JsonProperty("type") - protected Type _type; + private Type _type; /** * Obsolete ranges */ @JsonProperty("valid") - protected YearRange _valid; + private YearRange _valid; @JsonProperty("obsolete_new_code") - protected List _obsoleteNewCode; + private List _obsoleteNewCode; /** * Shared disease properties */ @JsonProperty("reportable") - protected List _reportable; + private List _reportable; @JsonProperty("abstractor_note") - protected List _abstractorNote; + private List _abstractorNote; @JsonProperty("treatment") - protected List _treatment; + private List _treatment; @JsonProperty("genetics") - protected List _genetics; + private List _genetics; @JsonProperty("alternate_name") - protected List _alternateName; + private List _alternateName; @JsonProperty("definition") - protected List _definition; + private List _definition; @JsonProperty("icdO2_morphology") - protected List _icdO2Morphology; + private List _icdO2Morphology; @JsonProperty("icdO1_morphology") - protected List _icdO1Morphology; + private List _icdO1Morphology; @JsonProperty("icd_10cm_code") - protected List _icd10CmCode; + private List _icd10CmCode; @JsonProperty("icd_10_code") - protected List _icd10Code; + private List _icd10Code; @JsonProperty("icd_9_code") - protected List _icd9Code; + private List _icd9Code; @JsonProperty("signs") - protected List _signs; + private List _signs; @JsonProperty("exams") - protected List _exams; + private List _exams; @JsonProperty("mortality") - protected List _mortality; + private List _mortality; + @JsonProperty("source") + private List _source; /** * Morphology ranges */ @JsonProperty("icdO3_effective") - protected YearRange _icdO3Effective; + private YearRange _icdO3Effective; @JsonProperty("icdO2_effective") - protected YearRange _icdO2Effective; + private YearRange _icdO2Effective; @JsonProperty("icdO1_effective") - protected YearRange _icdO1Effective; + private YearRange _icdO1Effective; /** * Hemato specific */ @JsonProperty("missing_primary_site_message") - protected List _missingPrimarySiteMessage; + private List _missingPrimarySiteMessage; @JsonProperty("grade") - protected List _grade; + private List _grade; @JsonProperty("transform_to") - protected List _transformTo; + private List _transformTo; @JsonProperty("transform_to_text") - protected List _transformToText; + private List _transformToText; @JsonProperty("transform_from") - protected List _transformFrom; + private List _transformFrom; @JsonProperty("transform_from_text") - protected List _transformFromText; + private List _transformFromText; @JsonProperty("immunophenotype") - protected List _immunophenotype; + private List _immunophenotype; @JsonProperty("diagnosis_method") - protected List _diagnosisMethod; + private List _diagnosisMethod; @JsonProperty("module_id") - protected List _moduleId; + private List _moduleId; @JsonProperty("same_primary") - protected List _samePrimaries; + private List _samePrimaries; @JsonProperty("same_primaries_text") - protected List _samePrimariesText; + private List _samePrimariesText; @JsonProperty("progression") - protected List _progression; + private List _progression; + @JsonProperty("diagnostic_confirmation") + private List _diagnosticConfirmation; /** * Solid tumor specific */ @JsonProperty("biomarkers") - protected List _biomarkers; + private List _biomarkers; @JsonProperty("treatment_text") - protected List _treatmentText; + private List _treatmentText; @JsonProperty("recurrence") - protected List _recurrence; + private List _recurrence; public List getHistory() { return _history; @@ -297,6 +302,14 @@ public void setMortality(List mortality) { _mortality = mortality; } + public List getSource() { + return _source; + } + + public void setSource(List source) { + _source = source; + } + public YearRange getIcdO3Effective() { return _icdO3Effective; } @@ -425,10 +438,22 @@ public void setTreatmentText(List treatmentText) { _treatmentText = treatmentText; } + public List getProgression() { + return _progression; + } + public void setProgression(List progression) { _progression = progression; } + public List getDiagnosticConfirmation() { + return _diagnosticConfirmation; + } + + public void setDiagnosticConfirmation(List diagnosticConfirmation) { + _diagnosticConfirmation = diagnosticConfirmation; + } + // values for the datasources public enum Type { SOLID_TUMOR, diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java index a74368f..0ddba06 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.disease; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class DiseaseChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class DiseaseChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class DiseaseChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java index bada339..1a24bd5 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java @@ -13,12 +13,6 @@ public class DiseaseChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public DiseaseChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java index 0d39063..003001d 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java @@ -87,11 +87,12 @@ public interface DiseaseService { * @param version Disease version * @param morphology1 ICD O3 Morphology * @param morphology2 ICD O3 Morphology - * @param year Year of Diagnosis + * @param year1 Year of Diagnosis1 + * @param year2 Year of Diagnosis2 * @return a SamePrimary object */ @GET("disease/{version}/same_primary") - Call samePrimaries(@Path("version") String version, @Query("d1") String morphology1, @Query("d2") String morphology2, @Query("year") String year); + Call samePrimaries(@Path("version") String version, @Query("d1") String morphology1, @Query("d2") String morphology2, @Query("year1") String year1, @Query("year2") String year2); /** * Returns the reportable year range of the supplied disease. diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java new file mode 100644 index 0000000..b0a40e4 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.disease; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"name", "section", "pages"}) +public class DiseaseSource { + + @JsonProperty("name") + private String _name; + @JsonProperty("section") + private String _section; + @JsonProperty("pages") + private String _pages; + + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + public String getSection() { + return _section; + } + + public void setSection(String section) { + _section = section; + } + + public String getPages() { + return _pages; + } + + public void setPages(String pages) { + _pages = pages; + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java b/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java index 71ce2fb..db12705 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java @@ -8,8 +8,10 @@ public class SamePrimaries { protected String _disease1; @JsonProperty("disease2") protected String _disease2; - @JsonProperty("year") - protected Integer _year; + @JsonProperty("year1") + protected Integer _year1; + @JsonProperty("year2") + protected Integer _year2; @JsonProperty("is_same") protected Boolean _isSame; @@ -29,16 +31,20 @@ public void setDisease2(String disease2) { _disease2 = disease2; } - public Integer getYear() { - return _year; + public Integer getYear1() { + return _year1; } - public void setYear(Integer year) { - _year = year; + public void setYear1(Integer year1) { + _year1 = year1; } - public Boolean isSame() { - return _isSame; + public Integer getYear2() { + return _year2; + } + + public void setYear2(Integer year2) { + _year2 = year2; } public Boolean getIsSame() { diff --git a/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java b/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java deleted file mode 100644 index 03456bf..0000000 --- a/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.disease; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class YearRangeBoolean extends YearRange { - - @JsonProperty("value") - protected Boolean _value; - - public Boolean getValue() { - return _value; - } - - public void setValue(Boolean value) { - _value = value; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java index cb57e53..efa9ecd 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.glossary; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class GlossaryChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class GlossaryChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class GlossaryChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java index 81886fa..ae8da9d 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java @@ -13,12 +13,6 @@ public class GlossaryChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public GlossaryChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java index f1dd0d5..5ef8542 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java @@ -8,11 +8,17 @@ import java.util.Set; import retrofit2.Call; +import retrofit2.http.Body; import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; + public interface GlossaryService { /** @@ -80,4 +86,15 @@ public interface GlossaryService { @GET("glossary/{version}/changelog") Call changelogs(@Path("version") String version, @Query("from") String fromDate, @Query("to") String toDate, @Query("count") Integer count); + /** + * Return a glossary results for a staging table + * @param text text to look up glossary references + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @Headers("Content-Type:text/plain") + @POST("glossary/match") + Call> match(@Body String text, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + } diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java new file mode 100644 index 0000000..13469da --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.hcpcs; + +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"hcpcs_code", "generic_name", "description", "brand_names", "strength", "fda_approval_year", "fda_discontinuation_year", "cms_approval_date", + "cms_discontinuation_date", "categories", "major_drug_class", "minor_drug_class", "oral", "date_added", "date_modified", "score"}) +public class Hcpcs { + + @JsonProperty("hcpcs_code") + private String hcpcsCode; + @JsonProperty("generic_name") + private String genericName; + @JsonProperty("description") + private String description; + @JsonProperty("brand_names") + private List brandNames; + @JsonProperty("strength") + private String strength; + @JsonProperty("fda_approval_year") + private String fdaApprovalYear; + @JsonProperty("fda_discontinuation_year") + private String fdaDiscontinuationYear; + @JsonProperty("cms_approval_date") + private String cmsApprovalDate; + @JsonProperty("cms_discontinuation_date") + private String cmsDiscontinuationDate; + @JsonProperty("categories") + private List categories; + @JsonProperty("major_drug_class") + private String majorDrugClass; + @JsonProperty("minor_drug_class") + private String minorDrugClass; + @JsonProperty("oral") + private Boolean oral; + @JsonProperty("date_added") + private Date dateAdded; + @JsonProperty("date_modified") + private Date dateModified; + @JsonProperty("score") + private Double score; + + public String getHcpcsCode() { + return hcpcsCode; + } + + public void setHcpcsCode(String hcpcsCode) { + this.hcpcsCode = hcpcsCode; + } + + public String getGenericName() { + return genericName; + } + + public void setGenericName(String genericName) { + this.genericName = genericName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getBrandNames() { + return brandNames; + } + + public void setBrandNames(List brandNames) { + this.brandNames = brandNames; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getFdaApprovalYear() { + return fdaApprovalYear; + } + + public void setFdaApprovalYear(String fdaApprovalYear) { + this.fdaApprovalYear = fdaApprovalYear; + } + + public String getFdaDiscontinuationYear() { + return fdaDiscontinuationYear; + } + + public void setFdaDiscontinuationYear(String fdaDiscontinuationYear) { + this.fdaDiscontinuationYear = fdaDiscontinuationYear; + } + + public String getCmsApprovalDate() { + return cmsApprovalDate; + } + + public void setCmsApprovalDate(String cmsApprovalDate) { + this.cmsApprovalDate = cmsApprovalDate; + } + + public String getCmsDiscontinuationDate() { + return cmsDiscontinuationDate; + } + + public void setCmsDiscontinuationDate(String cmsDiscontinuationDate) { + this.cmsDiscontinuationDate = cmsDiscontinuationDate; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public String getMajorDrugClass() { + return majorDrugClass; + } + + public void setMajorDrugClass(String majorDrugClass) { + this.majorDrugClass = majorDrugClass; + } + + public String getMinorDrugClass() { + return minorDrugClass; + } + + public void setMinorDrugClass(String minorDrugClass) { + this.minorDrugClass = minorDrugClass; + } + + public Boolean getOral() { + return oral; + } + + public void setOral(Boolean oral) { + this.oral = oral; + } + + public Date getDateAdded() { + return dateAdded; + } + + public void setDateAdded(Date dateAdded) { + this.dateAdded = dateAdded; + } + + public Date getDateModified() { + return dateModified; + } + + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; + } + + public Double getScore() { + return score; + } + + public void setScore(Double score) { + this.score = score; + } + + // drug categories + public enum Category { + HORMONAL_THERAPY, + ANCILLARY, + CHEMOTHERAPY, + IMMUNOTHERAPY, + RADIOPHARMACEUTICAL; + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java new file mode 100644 index 0000000..c30a889 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.hcpcs; + +import java.util.List; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; +import retrofit2.http.QueryMap; + +public interface HcpcsService { + + /** + * Return an HCPCS entity based on code. + * @param code HCPCS code + * @return an Hcpcs procedure + */ + @GET("hcpcs/code/{code}") + Call getProcedure(@Path("code") String code); + + /** + * Return a list of matching Hcpcs procedures + * @param searchParams A Map of search parameters. + * @return a List of Hcpcs procedures + */ + @GET("hcpcs") + Call> search(@QueryMap Map searchParams); + +} diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java index bab3fea..67c67cd 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java @@ -4,16 +4,6 @@ public class MphInput { - /** - * How to consider histology match, if it is strict 8000 is considered a different histology than 8010-9999 - * for rule : Do the tumors have ICD-O-3 histology codes that are different at the first (Xxxx), second (Xxxx), or third (xxXx) number? - * If lenient mode is on 8000 is considered as NOS and be considered to match any 8nnn histologies. - */ - public enum HistologyMatchMode { - STRICT, - LENIENT - } - @JsonProperty("primary_site") private String _primarySite; @JsonProperty("histology_icd_o3") @@ -32,8 +22,6 @@ public enum HistologyMatchMode { private String _dateOfDiagnosisMonth; @JsonProperty("date_of_diagnosis_day") private String _dateOfDiagnosisDay; - @JsonProperty("tx_status") - private String _txStatus; public String getPrimarySite() { return _primarySite; @@ -107,12 +95,4 @@ public void setDateOfDiagnosisDay(String dateOfDiagnosisDay) { _dateOfDiagnosisDay = dateOfDiagnosisDay; } - public String getTxStatus() { - return _txStatus; - } - - public void setTxStatus(String txStatus) { - _txStatus = txStatus; - } - } diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java index 3d4f8a3..966b60b 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java @@ -6,29 +6,18 @@ public class MphOutput { - // The possible results of determining if two tumors are single or multiple primaries. - public enum Result { - // indicates the two tumors are the same primary - SINGLE_PRIMARY, - // indicates the two tumors are different primaries - MULTIPLE_PRIMARIES, - // indicates there is not enough information to make a proper determination - QUESTIONABLE - } - @JsonProperty("result") private Result _result; - @JsonProperty("reason") - private String _reason; - @JsonProperty("applied_rules") - private List _appliedRules; @JsonProperty("group_id") private String _groupId; + @JsonProperty("group_name") + private String _groupName; @JsonProperty("step") private String _step; - - public MphOutput() { - } + @JsonProperty("reason") + private String _reason; + @JsonProperty("applied_rules") + private List _appliedRules; public Result getResult() { return _result; @@ -69,4 +58,15 @@ public String getStep() { public void setStep(String step) { _step = step; } + + // The possible results of determining if two tumors are single or multiple primaries. + public enum Result { + // indicates the two tumors are the same primary + SINGLE_PRIMARY, + // indicates the two tumors are different primaries + MULTIPLE_PRIMARIES, + // indicates there is not enough information to make a proper determination + QUESTIONABLE, + INVALID_INPUT + } } diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java b/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java index e3dab15..329cb26 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java @@ -22,9 +22,6 @@ public class MphRule { @JsonProperty("examples") private List _examples; - public MphRule() { - } - public String getGroupId() { return _groupId; } diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java index adb9dc7..e86fa8f 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java @@ -6,27 +6,15 @@ import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; -import retrofit2.http.Query; - -import com.imsweb.seerapi.client.mph.MphInput.HistologyMatchMode; public interface MphService { - /** - * Uses multiple primary rules to compare two diseases using strict histology matching mode - * @param pair a pair of diseases - * @return a result indicating whether the two diseases are the same primary - */ - @POST("mph") - Call mph(@Body MphInputPair pair); - /** * Uses multiple primary rules to compare two diseases * @param pair a pair of diseases - * @param matchMode * @return a result indicating whether the two diseases are the same primary */ @POST("mph") - Call mph(@Body MphInputPair pair, @Query("histology-matching-mode") HistologyMatchMode matchMode); + Call mph(@Body MphInputPair pair); } \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java new file mode 100644 index 0000000..414b345 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java @@ -0,0 +1,27 @@ +package com.imsweb.seerapi.client.naaccr; + +public class AllowedCode { + + private String code; + private String description; + + public AllowedCode() { + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java deleted file mode 100644 index 4b79e68..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NaaccrField { - - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - @JsonProperty("start_col") - protected Integer _start; - @JsonProperty("end_col") - protected Integer _end; - @JsonProperty("alignment") - protected String _align; - @JsonProperty("padding_char") - protected String _padChar; - @JsonProperty("documentation") - protected String _documentation; - @JsonProperty("subfield") - protected List _subFields; - - public Integer getItem() { - return _item; - } - - public void setItem(Integer item) { - _item = item; - } - - public String getName() { - return _name; - } - - public void setName(String name) { - _name = name; - } - - public Integer getStart() { - return _start; - } - - public void setStart(Integer start) { - _start = start; - } - - public Integer getEnd() { - return _end; - } - - public void setEnd(Integer end) { - _end = end; - } - - public String getAlign() { - return _align; - } - - public void setAlign(String align) { - _align = align; - } - - public String getPadChar() { - return _padChar; - } - - public void setPadChar(String padChar) { - _padChar = padChar; - } - - public String getDocumentation() { - return _documentation; - } - - public void setDocumentation(String documentation) { - _documentation = documentation; - } - - public List getSubFields() { - return _subFields; - } - - public void setSubFields(List subFields) { - _subFields = subFields; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java deleted file mode 100644 index b19dd61..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NaaccrFieldName { - - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - - public Integer getItem() { - return _item; - } - - public void setItem(Integer item) { - _item = item; - } - - public String getName() { - return _name; - } - - public void setName(String name) { - _name = name; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java new file mode 100644 index 0000000..39c9683 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java @@ -0,0 +1,305 @@ +package com.imsweb.seerapi.client.naaccr; + +import java.time.OffsetDateTime; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NaaccrItem { + + private NaaccrVersion version; + private String itemNumber; + private String itemName; + private String itemLength; + private String yearImplemented; + private String yearRetired; + private String versionImplemented; + private String versionRetired; + private String xmlNaaccrId; + private String xmlParentId; + private List recordTypes; + private String section; + private String sourceOfStandard; + private OffsetDateTime dateCreated; + private OffsetDateTime dateModified; + private String description; + private String rationale; + private String generalNotes; + private String clarification; + private String npcrCollect; + private String cocCollect; + private String seerCollect; + private String cccrCollect; + private List alternateNames; + private String format; + private String codeNote; + private String codeDescription; + private String itemDataType; + private String allowableValues; + private List allowedCodes; + + public NaaccrVersion getVersion() { + return version; + } + + public void setVersion(NaaccrVersion version) { + this.version = version; + } + + @JsonProperty("item_number") + public String getItemNumber() { + return itemNumber; + } + + public void setItemNumber(String itemNumber) { + this.itemNumber = itemNumber; + } + + @JsonProperty("item_name") + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + @JsonProperty("item_length") + public String getItemLength() { + return itemLength; + } + + public void setItemLength(String itemLength) { + this.itemLength = itemLength; + } + + @JsonProperty("year_implemented") + public String getYearImplemented() { + return yearImplemented; + } + + public void setYearImplemented(String yearImplemented) { + this.yearImplemented = yearImplemented; + } + + @JsonProperty("year_retired") + public String getYearRetired() { + return yearRetired; + } + + public void setYearRetired(String yearRetired) { + this.yearRetired = yearRetired; + } + + @JsonProperty("version_implemented") + public String getVersionImplemented() { + return versionImplemented; + } + + public void setVersionImplemented(String versionImplemented) { + this.versionImplemented = versionImplemented; + } + + @JsonProperty("version_retired") + public String getVersionRetired() { + return versionRetired; + } + + public void setVersionRetired(String versionRetired) { + this.versionRetired = versionRetired; + } + + @JsonProperty("xml_naaccr_id") + public String getXmlNaaccrId() { + return xmlNaaccrId; + } + + public void setXmlNaaccrId(String xmlNaaccrId) { + this.xmlNaaccrId = xmlNaaccrId; + } + + @JsonProperty("xml_parent_id") + public String getXmlParentId() { + return xmlParentId; + } + + public void setXmlParentId(String xmlParentId) { + this.xmlParentId = xmlParentId; + } + + @JsonProperty("record_types") + public List getRecordTypes() { + return recordTypes; + } + + public void setRecordTypes(List recordTypes) { + this.recordTypes = recordTypes; + } + + public String getSection() { + return section; + } + + public void setSection(String section) { + this.section = section; + } + + @JsonProperty("source_of_standard") + public String getSourceOfStandard() { + return sourceOfStandard; + } + + public void setSourceOfStandard(String sourceOfStandard) { + this.sourceOfStandard = sourceOfStandard; + } + + @JsonProperty("date_created") + public OffsetDateTime getDateCreated() { + return dateCreated; + } + + public void setDateCreated(OffsetDateTime dateCreated) { + this.dateCreated = dateCreated; + } + + @JsonProperty("date_modified") + public OffsetDateTime getDateModified() { + return dateModified; + } + + public void setDateModified(OffsetDateTime dateModified) { + this.dateModified = dateModified; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRationale() { + return rationale; + } + + public void setRationale(String rationale) { + this.rationale = rationale; + } + + @JsonProperty("general_notes") + public String getGeneralNotes() { + return generalNotes; + } + + public void setGeneralNotes(String generalNotes) { + this.generalNotes = generalNotes; + } + + public String getClarification() { + return clarification; + } + + public void setClarification(String clarification) { + this.clarification = clarification; + } + + @JsonProperty("npcr_collect") + public String getNpcrCollect() { + return npcrCollect; + } + + public void setNpcrCollect(String npcrCollect) { + this.npcrCollect = npcrCollect; + } + + @JsonProperty("coc_collect") + public String getCocCollect() { + return cocCollect; + } + + public void setCocCollect(String cocCollect) { + this.cocCollect = cocCollect; + } + + @JsonProperty("seer_collect") + public String getSeerCollect() { + return seerCollect; + } + + public void setSeerCollect(String seerCollect) { + this.seerCollect = seerCollect; + } + + @JsonProperty("cccr_collect") + public String getCccrCollect() { + return cccrCollect; + } + + public void setCccrCollect(String cccrCollect) { + this.cccrCollect = cccrCollect; + } + + @JsonProperty("alternate_names") + public List getAlternateNames() { + return alternateNames; + } + + public void setAlternateNames(List alternateNames) { + this.alternateNames = alternateNames; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + @JsonProperty("code_note") + public String getCodeNote() { + return codeNote; + } + + public void setCodeNote(String codeNote) { + this.codeNote = codeNote; + } + + @JsonProperty("code_description") + public String getCodeDescription() { + return codeDescription; + } + + public void setCodeDescription(String codeDescription) { + this.codeDescription = codeDescription; + } + + @JsonProperty("item_data_type") + public String getItemDataType() { + return itemDataType; + } + + public void setItemDataType(String itemDataType) { + this.itemDataType = itemDataType; + } + + @JsonProperty("allowable_values") + public String getAllowableValues() { + return allowableValues; + } + + public void setAllowableValues(String allowableValues) { + this.allowableValues = allowableValues; + } + + @JsonProperty("allowed_codes") + public List getAllowedCodes() { + return allowedCodes; + } + + public void setAllowedCodes(List allowedCodes) { + this.allowedCodes = allowedCodes; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java new file mode 100644 index 0000000..cefeee6 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java @@ -0,0 +1,36 @@ +package com.imsweb.seerapi.client.naaccr; + +public class NaaccrItemInfo { + + private String id; + private String item; + private String name; + + public NaaccrItemInfo() { + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java index eebc8a4..c2b9609 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java @@ -24,15 +24,15 @@ public interface NaaccrService { * @return a list of NaaccrFieldName objects */ @GET("naaccr/{version}") - Call> fieldNames(@Path("version") String version); + Call> fieldNames(@Path("version") String version); /** - * Return a list of all the field identifiers and names from a specified NAACCR version + * Return a single item from a NAACCR version * @param version NAACCR version - * @param item NAACCR item number - * @return a list of NaaccrFieldName objects + * @param item NAACCR item number or XML identifier + * @return a NaaccrItem */ - @GET("naaccr/{version}/item/{item}") - Call field(@Path("version") String version, @Path("item") Integer item); + @GET("naaccr/{version}/{item}") + Call item(@Path("version") String version, @Path("item") String item); } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java deleted file mode 100644 index 22ae47b..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NaaccrSubField { - - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - @JsonProperty("start_col") - protected Integer _start; - @JsonProperty("end_col") - protected Integer _end; - @JsonProperty("alignment") - protected String _align; - @JsonProperty("padding_char") - protected String _padChar; - - public Integer getItem() { - return _item; - } - - public void setItem(Integer item) { - _item = item; - } - - public String getName() { - return _name; - } - - public void setName(String name) { - _name = name; - } - - public Integer getStart() { - return _start; - } - - public void setStart(Integer start) { - _start = start; - } - - public Integer getEnd() { - return _end; - } - - public void setEnd(Integer end) { - _end = end; - } - - public String getAlign() { - return _align; - } - - public void setAlign(String align) { - _align = align; - } - - public String getPadChar() { - return _padChar; - } - - public void setPadChar(String padChar) { - _padChar = padChar; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java index ad08b8b..c9be312 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java @@ -1,57 +1,41 @@ package com.imsweb.seerapi.client.naaccr; +import java.time.OffsetDateTime; + import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +@JsonPropertyOrder({"version", "year_implemented", "date_of_publication"}) public class NaaccrVersion { - @JsonProperty("version") - protected String _version; - @JsonProperty("name") - protected String _name; - @JsonProperty("length") - protected Integer _length; - @JsonProperty("description") - protected String _description; - @JsonProperty("style") - protected String _style; + private String version; + private Integer yearImplemented; + private OffsetDateTime dateOfPublication; public String getVersion() { - return _version; + return version; } public void setVersion(String version) { - _version = version; - } - - public String getName() { - return _name; - } - - public void setName(String name) { - _name = name; - } - - public Integer getLength() { - return _length; + this.version = version; } - public void setLength(Integer length) { - _length = length; + @JsonProperty("year_implemented") + public Integer getYearImplemented() { + return yearImplemented; } - public String getDescription() { - return _description; + public void setYearImplemented(Integer yearImplemented) { + this.yearImplemented = yearImplemented; } - public void setDescription(String description) { - _description = description; + @JsonProperty("date_of_publication") + public OffsetDateTime getDateOfPublication() { + return dateOfPublication; } - public String getStyle() { - return _style; + public void setDateOfPublication(OffsetDateTime dateOfPublication) { + this.dateOfPublication = dateOfPublication; } - public void setStyle(String style) { - _style = style; - } -} +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java index 2f8673d..5521536 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java @@ -10,23 +10,43 @@ public class NdcPackage { @JsonProperty("package") - private String _code; + private String code; @JsonProperty("description") - private String _description; + private String description; + @JsonProperty("start_marketing_date") + private String startMarketingDate; + @JsonProperty("end_marketing_date") + private String endMarketingDate; public String getCode() { - return _code; + return code; } public void setCode(String code) { - _code = code; + this.code = code; } public String getDescription() { - return _description; + return description; } public void setDescription(String description) { - _description = description; + this.description = description; + } + + public String getStartMarketingDate() { + return startMarketingDate; + } + + public void setStartMarketingDate(String startMarketingDate) { + this.startMarketingDate = startMarketingDate; + } + + public String getEndMarketingDate() { + return endMarketingDate; + } + + public void setEndMarketingDate(String endMarketingDate) { + this.endMarketingDate = endMarketingDate; } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java index 019315d..e9510d3 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java @@ -15,118 +15,213 @@ public class NdcProduct { @JsonProperty("ndc") - private String _ndc; + private String ndc; @JsonProperty("type_name") - private String _typeName; + private String typeName; @JsonProperty("proprietary_name") - private String _proprietaryName; + private String proprietaryName; @JsonProperty("proprietary_name_suffix") - private String _proprietaryNameSuffix; + private String proprietaryNameSuffix; @JsonProperty("non_proprietary_name") - private List _nonProprietaryName; + private List nonProprietaryName; @JsonProperty("dosage_form_name") - private String _dosageFormName; + private String dosageFormName; @JsonProperty("route_name") - private List _routeName; + private List routeName; @JsonProperty("start_marketing_date") - private String _startMarketingDate; + private String startMarketingDate; @JsonProperty("end_marketing_date") - private String _endMarketingDate; + private String endMarketingDate; @JsonProperty("marketing_category_name") - private String _marketingCategoryName; + private String marketingCategoryName; @JsonProperty("application_number") - private String _applicationNumber; + private String applicationNumber; @JsonProperty("labeler_name") - private String _labelerName; + private String labelerName; @JsonProperty("dea_schedule") - private String _deaSchedule; + private String deaSchedule; @JsonProperty("substances") - private List _substances; + private List substances; @JsonProperty("pharm_class") - private List _pharmClass; + private List pharmClass; @JsonProperty("packages") - private List _packages; + private List packages; @JsonProperty("date_added") - private Date _dateAdded; + private Date dateAdded; @JsonProperty("date_modified") - private Date _dateModified; + private Date dateModified; @JsonProperty("date_removed") - private Date _dateRemoved; + private Date dateRemoved; + @JsonProperty("seer") + private NdcSeerInfo seerInfo; + @JsonProperty("score") + private Double score; public String getNdc() { - return _ndc; + return ndc; + } + + public void setNdc(String ndc) { + this.ndc = ndc; } public String getTypeName() { - return _typeName; + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; } public String getProprietaryName() { - return _proprietaryName; + return proprietaryName; + } + + public void setProprietaryName(String proprietaryName) { + this.proprietaryName = proprietaryName; } public String getProprietaryNameSuffix() { - return _proprietaryNameSuffix; + return proprietaryNameSuffix; + } + + public void setProprietaryNameSuffix(String proprietaryNameSuffix) { + this.proprietaryNameSuffix = proprietaryNameSuffix; } public List getNonProprietaryName() { - return _nonProprietaryName; + return nonProprietaryName; + } + + public void setNonProprietaryName(List nonProprietaryName) { + this.nonProprietaryName = nonProprietaryName; } public String getDosageFormName() { - return _dosageFormName; + return dosageFormName; + } + + public void setDosageFormName(String dosageFormName) { + this.dosageFormName = dosageFormName; } public List getRouteName() { - return _routeName; + return routeName; + } + + public void setRouteName(List routeName) { + this.routeName = routeName; } public String getStartMarketingDate() { - return _startMarketingDate; + return startMarketingDate; + } + + public void setStartMarketingDate(String startMarketingDate) { + this.startMarketingDate = startMarketingDate; } public String getEndMarketingDate() { - return _endMarketingDate; + return endMarketingDate; + } + + public void setEndMarketingDate(String endMarketingDate) { + this.endMarketingDate = endMarketingDate; } public String getMarketingCategoryName() { - return _marketingCategoryName; + return marketingCategoryName; + } + + public void setMarketingCategoryName(String marketingCategoryName) { + this.marketingCategoryName = marketingCategoryName; } public String getApplicationNumber() { - return _applicationNumber; + return applicationNumber; + } + + public void setApplicationNumber(String applicationNumber) { + this.applicationNumber = applicationNumber; } public String getLabelerName() { - return _labelerName; + return labelerName; + } + + public void setLabelerName(String labelerName) { + this.labelerName = labelerName; } public String getDeaSchedule() { - return _deaSchedule; + return deaSchedule; + } + + public void setDeaSchedule(String deaSchedule) { + this.deaSchedule = deaSchedule; } public List getSubstances() { - return _substances; + return substances; + } + + public void setSubstances(List substances) { + this.substances = substances; } public List getPharmClass() { - return _pharmClass; + return pharmClass; + } + + public void setPharmClass(List pharmClass) { + this.pharmClass = pharmClass; } public List getPackages() { - return _packages; + return packages; + } + + public void setPackages(List packages) { + this.packages = packages; } public Date getDateAdded() { - return _dateAdded; + return dateAdded; + } + + public void setDateAdded(Date dateAdded) { + this.dateAdded = dateAdded; } public Date getDateModified() { - return _dateModified; + return dateModified; + } + + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; } public Date getDateRemoved() { - return _dateRemoved; + return dateRemoved; + } + + public void setDateRemoved(Date dateRemoved) { + this.dateRemoved = dateRemoved; + } + + public NdcSeerInfo getSeerInfo() { + return seerInfo; } + public void setSeerInfo(NdcSeerInfo seerInfo) { + this.seerInfo = seerInfo; + } + + public Double getScore() { + return score; + } + + public void setScore(Double score) { + this.score = score; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java index 9c750de..37441c8 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java @@ -6,9 +6,13 @@ import java.util.HashMap; import java.util.Map; +import com.imsweb.seerapi.client.ndc.NdcSeerInfo.Category; + public class NdcSearch { private String _query; + private Category _category; + private Boolean _hasSeerInfo; private Boolean _includeRemoved; private String _addedSince; private String _modifiedSince; @@ -25,12 +29,28 @@ public void setQuery(String query) { _query = query; } + public Category getCategory() { + return _category; + } + + public void setCategory(Category category) { + _category = category; + } + + public Boolean getHasSeerInfo() { + return _hasSeerInfo; + } + + public void setHasSeerInfo(Boolean hasSeerInfo) { + _hasSeerInfo = hasSeerInfo; + } + public Boolean getIncludeRemoved() { return _includeRemoved; } public void setIncludeRemoved(Boolean includeRemoved) { - this._includeRemoved = includeRemoved; + _includeRemoved = includeRemoved; } public String getAddedSince() { @@ -77,8 +97,8 @@ public String getOrder() { return _order; } - public void setOrder(String orderBy) { - _order = orderBy; + public void setOrder(String order) { + _order = order; } /** @@ -90,8 +110,12 @@ public Map paramMap() { if (getQuery() != null) params.put("q", getQuery()); + if (getCategory() != null) + params.put("category", getCategory().toString()); + if (getHasSeerInfo() != null) + params.put("has_seer_info", getHasSeerInfo().toString()); if (getIncludeRemoved() != null) - params.put("include_removed", getIncludeRemoved() ? "true" : "false"); + params.put("include_removed", Boolean.TRUE.equals(getIncludeRemoved()) ? "true" : "false"); if (getAddedSince() != null) params.put("added_since", getAddedSince()); if (getModifiedSince() != null) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java new file mode 100644 index 0000000..a8c5d8f --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2018 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.ndc; + +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"seer_rx_id", "categories", "major_drug_class", "minor_drug_class", "orphan_drug", "exclusive_oncologic_agent", "date_modified"}) +@JsonIgnoreProperties(ignoreUnknown = true) +public class NdcSeerInfo { + + @JsonProperty("seer_rx_id") + private String seerRxId; + @JsonProperty("categories") + private List categories; + @JsonProperty("major_drug_class") + private String majorDrugClass; + @JsonProperty("minor_drug_class") + private String minorDrugClass; + @JsonProperty("orphan_drug") + private Boolean orphanDrug; + @JsonProperty("exclusive_oncologic_agent") + private Boolean exclusiveAgent; + @JsonProperty("date_modified") + private Date dateModified; + + public String getSeerRxId() { + return seerRxId; + } + + public void setSeerRxId(String seerRxId) { + this.seerRxId = seerRxId; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public String getMajorDrugClass() { + return majorDrugClass; + } + + public void setMajorDrugClass(String majorDrugClass) { + this.majorDrugClass = majorDrugClass; + } + + public String getMinorDrugClass() { + return minorDrugClass; + } + + public void setMinorDrugClass(String minorDrugClass) { + this.minorDrugClass = minorDrugClass; + } + + public Boolean getOrphanDrug() { + return orphanDrug; + } + + public void setOrphanDrug(Boolean orphanDrug) { + this.orphanDrug = orphanDrug; + } + + public Boolean getExclusiveAgent() { + return exclusiveAgent; + } + + public void setExclusiveAgent(Boolean exclusiveAgent) { + this.exclusiveAgent = exclusiveAgent; + } + + public Date getDateModified() { + return dateModified; + } + + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; + } + + // drug categories + public enum Category { + HORMONAL_THERAPY, + ANCILLARY, + CHEMOTHERAPY, + IMMUNOTHERAPY, + RADIOPHARMACEUTICAL + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java index e917d0e..3518a44 100644 --- a/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java @@ -11,12 +11,6 @@ public class PublishableChangelogResults { protected Integer _count; protected Integer _offset; - /** - * Default constructor - */ - public PublishableChangelogResults() { - } - @JsonProperty("total") public Long getTotal() { return _total; diff --git a/src/main/java/com/imsweb/seerapi/client/rx/Rx.java b/src/main/java/com/imsweb/seerapi/client/rx/Rx.java index bc84885..c109c6c 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/Rx.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/Rx.java @@ -40,12 +40,6 @@ public class Rx extends Publishable { @JsonProperty("radiation") protected String _radiation; - /** - * Default constructor - */ - public Rx() { - } - public List getHistory() { return _history; } diff --git a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java index 0e88953..5c0aa4c 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.rx; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class RxChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class RxChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class RxChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java index 1b6d5ff..9381302 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java @@ -13,12 +13,6 @@ public class RxChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public RxChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java b/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java new file mode 100644 index 0000000..db7b652 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.shared; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Changelog { + + @JsonProperty("user") + private String _user; + @JsonProperty("date") + private Date _date; + @JsonProperty("version") + private String _version; + @JsonProperty("description") + private String _description; + + public String getUser() { + return _user; + } + + public void setUser(String user) { + _user = user; + } + + public Date getDate() { + return _date; + } + + public void setDate(Date date) { + _date = date; + } + + public String getVersion() { + return _version; + } + + public void setVersion(String version) { + _version = version; + } + + public String getDescription() { + return _description; + } + + public void setDescription(String description) { + _description = description; + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java b/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java index 29cd1c9..8da5be7 100644 --- a/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java +++ b/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java @@ -11,10 +11,16 @@ public class KeywordMatch { @JsonProperty("id") private String _id; + @JsonProperty("name") + private String _name; @JsonProperty("keyword") private String _keyword; @JsonProperty("category") private Set _category; + @JsonProperty("start") + private Integer _start; + @JsonProperty("end") + private Integer _end; public String getId() { return _id; @@ -24,6 +30,14 @@ public void setId(String id) { _id = id; } + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + public String getKeyword() { return _keyword; } @@ -39,4 +53,20 @@ public Set getCategory() { public void setCategory(Set category) { _category = category; } + + public Integer getStart() { + return _start; + } + + public void setStart(Integer start) { + _start = start; + } + + public Integer getEnd() { + return _end; + } + + public void setEnd(Integer end) { + _end = end; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java new file mode 100644 index 0000000..3d7a72e --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.siterecode; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SiteGroupAlgorithm { + + private String id; + private String name; + private String version; + @JsonProperty("required_input") + private List requiredInput; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public List getRequiredInput() { + return requiredInput; + } + + public void setRequiredInput(List requiredInput) { + this.requiredInput = requiredInput; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java index 64e4686..38e711c 100644 --- a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java @@ -11,6 +11,8 @@ public class SiteRecode { protected String _site; @JsonProperty("hist") protected String _hist; + @JsonProperty("behavior") + protected String _behavior; @JsonProperty("site_group") protected String _siteGroup; @@ -30,6 +32,14 @@ public void setHist(String hist) { _hist = hist; } + public String getBehavior() { + return _behavior; + } + + public void setBehavior(String behavior) { + _behavior = behavior; + } + public String getSiteGroup() { return _siteGroup; } diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java index 0ae0956..125df9b 100644 --- a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java @@ -3,28 +3,31 @@ */ package com.imsweb.seerapi.client.siterecode; +import java.util.List; + import retrofit2.Call; import retrofit2.http.GET; +import retrofit2.http.Path; import retrofit2.http.Query; -import com.imsweb.seerapi.client.shared.Version; - public interface SiteRecodeService { /** - * Return the version of the SEER Site Recode database. - * @return a String representing the database version + * Return the supported algorithms and versions + * @return a list of information about the algorithms */ - @GET("recode/version") - Call version(); + @GET("recode/sitegroup/algorithms") + Call> algorithms(); /** - * Return the SEER Site Group for the site/histology combination, or 99999 if the combination is unknown. + * Return the specified algorithm site group for the site/histology/behavior combination, or 99999 if the combination is unknown. + * @param algorithm site group algorithm * @param site Primary Site O3 * @param hist Histology O3 + * @param behavior Behavior O3 * @return a SiteRecode object based on the site and histology */ - @GET("recode/sitegroup") - Call siteGroup(@Query("site") String site, @Query("hist") String hist); + @GET("recode/sitegroup/{algorithm}") + Call siteGroup(@Path("algorithm") String algorithm, @Query("site") String site, @Query("hist") String hist, @Query("behavior") String behavior); } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java index 8be0e86..8735a83 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java @@ -3,6 +3,7 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -41,7 +42,7 @@ public SchemaLookup(String site, String histology) { * @return a set of keys */ public Set getAllowedKeys() { - return null; + return Collections.emptySet(); } /** @@ -67,7 +68,7 @@ public String getInput(String key) { * @param value value of input */ public void setInput(String key, String value) { - if (getAllowedKeys() != null && !getAllowedKeys().contains(key)) + if (!getAllowedKeys().isEmpty() && !getAllowedKeys().contains(key)) throw new IllegalStateException("The input key " + key + " is not allowed for lookups"); _inputs.put(key, value); @@ -116,13 +117,14 @@ public void setHistology(String hist) { * Return true if the inputs contain a discriminator. A key that is not site or hist which has a non-null/non-empty value is considered a discriminator * @return true or false indicating whether a discriminator exists */ + @SuppressWarnings("java:S135") public boolean hasDiscriminator() { boolean hasDiscriminator = false; for (Entry entry : _inputs.entrySet()) { String key = entry.getKey(); - if (StagingData.STANDARD_LOOKUP_KEYS.contains(key)) + if (StagingData._STANDARD_LOOKUP_KEYS.contains(key)) continue; String value = entry.getValue(); @@ -137,8 +139,10 @@ public boolean hasDiscriminator() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (!(o instanceof SchemaLookup)) + return false; SchemaLookup lookup = (SchemaLookup)o; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java index b3aac97..5c29d30 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java @@ -13,9 +13,6 @@ public class StagingAlgorithm { private String _name; private String _description; - /** - * Morphia requires a default constructor - */ public StagingAlgorithm() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java deleted file mode 100644 index 6340bb7..0000000 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.imsweb.seerapi.client.staging; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"table", "code", "is_valid"}) -public class StagingCode { - - protected String _table; - protected String _code; - protected Boolean _isValid; - - /** - * Default constructor - */ - public StagingCode() { - setIsValid(false); - } - - /** - * @param table Table identifier - * @param code Code - * @param isValid Boolean indicating whether code is value - */ - public StagingCode(String table, String code, Boolean isValid) { - setTable(table); - setCode(code); - setIsValid(isValid); - } - - @JsonProperty("table") - public String getTable() { - return _table; - } - - public void setTable(String table) { - _table = table; - } - - @JsonProperty("code") - public String getCode() { - return _code; - } - - public void setCode(String code) { - _code = code; - } - - @JsonProperty("is_valid") - public Boolean getIsValid() { - return _isValid; - } - - public void setIsValid(Boolean isValid) { - _isValid = isValid; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java index 2fa404a..3ec6165 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java @@ -20,9 +20,6 @@ enum ColumnType { ENDPOINT } - /** - * Morphia requires a default constructor - */ public StagingColumnDefinition() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java index 59ecc60..643562e 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java @@ -24,7 +24,7 @@ public class StagingData { public static final String YEAR_DX_KEY = "year_dx"; // set of keys that are standard for all schema lookups; any other keys are considered a discriminator - public static final Set STANDARD_LOOKUP_KEYS = new HashSet<>(Arrays.asList(PRIMARY_SITE_KEY, HISTOLOGY_KEY)); + protected static final Set _STANDARD_LOOKUP_KEYS = new HashSet<>(Arrays.asList(PRIMARY_SITE_KEY, HISTOLOGY_KEY)); private Result _result; private String _schemaId; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java deleted file mode 100644 index d9328ef..0000000 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2014 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.staging; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"type", "value", "result_key"}) -public class StagingEndpoint { - - private EndpointType _type; - private String _value; - private String _resultKey; - - enum EndpointType { - JUMP, - VALUE, - MATCH, - STOP, - ERROR - } - - public StagingEndpoint() { - } - - public StagingEndpoint(EndpointType type, String value) { - _type = type; - _value = value; - } - - @JsonProperty("type") - public EndpointType getType() { - return _type; - } - - public void setType(EndpointType type) { - _type = type; - } - - @JsonProperty("value") - public String getValue() { - return _value; - } - - public void setValue(String value) { - _value = value; - } - - @JsonProperty("result_key") - public String getResultKey() { - return _resultKey; - } - - public void setResultKey(String resultKey) { - _resultKey = resultKey; - } - -} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java index 3f583ea..335a547 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java @@ -3,49 +3,23 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * An error object */ -@JsonPropertyOrder({"type", "table", "key", "message"}) +@JsonPropertyOrder({"type", "table", "columns", "key", "message"}) public class StagingError { private Type _type; private String _table; + private List _columns; private String _key; private String _message; - public enum Type { - // an input key was supplied that is not defined in the input definition - UNKNOWN_INPUT, - - // a required input value was not contained in the input definition table - INVALID_REQUIRED_INPUT, - - // a non-required input value was not contained in the input definition table - INVALID_NON_REQUIRED_INPUT, - - // an input mapping from value did not exist - UNKNOWN_INPUT_MAPPING, - - // an ERROR endpoint was hit during staging processing - STAGING_ERROR, - - // a table was processed during staging and no match was found - MATCH_NOT_FOUND, - - // a specified table does not exist - UNKNOWN_TABLE, - - // processing a table ended up in an infinite loop due to JUMPs - INFINITE_LOOP, - - // an output value was produced which was not contained in the output definition table - INVALID_OUTPUT - } - /** * Default constructor (required for Jackson) */ @@ -78,6 +52,15 @@ public void setTable(String table) { _table = table; } + @JsonProperty("columns") + public List getColumns() { + return _columns; + } + + public void setColumns(List columns) { + _columns = columns; + } + @JsonProperty("key") public String getKey() { return _key; @@ -96,4 +79,33 @@ public void setMessage(String message) { _message = message; } + public enum Type { + // an input key was supplied that is not defined in the input definition + UNKNOWN_INPUT, + + // a required input value was not contained in the input definition table + INVALID_REQUIRED_INPUT, + + // a non-required input value was not contained in the input definition table + INVALID_NON_REQUIRED_INPUT, + + // an input mapping from value did not exist + UNKNOWN_INPUT_MAPPING, + + // an ERROR endpoint was hit during staging processing + STAGING_ERROR, + + // a table was processed during staging and no match was found + MATCH_NOT_FOUND, + + // a specified table does not exist + UNKNOWN_TABLE, + + // processing a table ended up in an infinite loop due to JUMPs + INFINITE_LOOP, + + // an output value was produced which was not contained in the output definition table + INVALID_OUTPUT + } + } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java new file mode 100644 index 0000000..f1538c1 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java @@ -0,0 +1,79 @@ +package com.imsweb.seerapi.client.staging; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonPropertyOrder({"name", "start", "end"}) +@JsonDeserialize(using = StagingMetadataDeserializer.class) +public class StagingMetadata { + + private String _name; + private Integer _start; + private Integer _end; + + public StagingMetadata() { + } + + public StagingMetadata(String name) { + _name = name; + } + + public StagingMetadata(String name, Integer start) { + _name = name; + _start = start; + } + + public StagingMetadata(String name, Integer start, Integer end) { + _name = name; + _start = start; + _end = end; + } + + @JsonProperty("name") + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + @JsonProperty("start") + public Integer getStart() { + return _start; + } + + public void setStart(Integer start) { + _start = start; + } + + @JsonProperty("end") + public Integer getEnd() { + return _end; + } + + public void setEnd(Integer end) { + _end = end; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + StagingMetadata that = (StagingMetadata)o; + return Objects.equals(_name, that._name) && + Objects.equals(_start, that._start) && + Objects.equals(_end, that._end); + } + + @Override + public int hashCode() { + return Objects.hash(_name, _start, _end); + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java new file mode 100644 index 0000000..089cb81 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java @@ -0,0 +1,42 @@ +package com.imsweb.seerapi.client.staging; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class StagingMetadataDeserializer extends StdDeserializer { + + public StagingMetadataDeserializer() { + this(null); + } + + protected StagingMetadataDeserializer(Class vc) { + super(vc); + } + + @Override + public StagingMetadata deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + JsonNode node = jp.getCodec().readTree(jp); + + if (node.isNull()) + return null; + + if (node.isObject()) { + StagingMetadata meta = new StagingMetadata(); + + if (node.get("name") != null) + meta.setName(node.get("name").asText()); + if (node.get("start") != null) + meta.setStart(node.get("start").asInt()); + if (node.get("end") != null) + meta.setEnd(node.get("end").asInt()); + + return meta; + } + + return new StagingMetadata(node.asText()); + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java index 30f06d2..2fce171 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java @@ -6,10 +6,8 @@ import java.util.Date; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -48,12 +46,6 @@ public enum StagingInputErrorHandler { private Set _involvedTables; private StagingInputErrorHandler _onInvalidInput; - /** - * Morphia requires a default constructor - */ - public StagingSchema() { - } - @JsonProperty("id") public String getId() { return _displayId; @@ -200,11 +192,6 @@ public void setMappings(List mapping) { _mappings = mapping; } - @JsonIgnore - public Map getInputMap() { - return null; - } - @JsonProperty("involved_tables") public Set getInvolvedTables() { return _involvedTables; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java index 346d3ba..2e361ca 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java @@ -3,31 +3,27 @@ */ package com.imsweb.seerapi.client.staging; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "values", "default", "table", "used_for_staging", "fail_on_invalid", "unit", "decimal_places", "metadata"}) +@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "values", "default", "table", "used_for_staging", "fail_on_invalid", "unit", "decimal_places", "metadata"}) public class StagingSchemaInput { private String _key; private String _name; private String _description; private Integer _naaccrItem; + private String _naaccrXmlId; private String _default; private String _table; private Boolean _usedForStaging; private String _unit; private Integer _decimalPlaces; - private Set _metadata; + private List _metadata; - /** - * Morphia requires a default constructor - */ public StagingSchemaInput() { } @@ -51,10 +47,11 @@ public StagingSchemaInput(StagingSchemaInput other) { setName(other.getName()); setDescription(other.getDescription()); setNaaccrItem(other.getNaaccrItem()); + setNaaccrXmlId(other.getNaaccrXmlId()); setDefault(other.getDefault()); setTable(other.getTable()); if (other.getMetadata() != null) - setMetadata(new HashSet<>(other.getMetadata())); + setMetadata(new ArrayList<>(other.getMetadata())); setUsedForStaging(other.getUsedForStaging()); setUnit(other.getUnit()); setDecimalPlaces(other.getDecimalPlaces()); @@ -96,6 +93,15 @@ public void setNaaccrItem(Integer naaccrItem) { _naaccrItem = naaccrItem; } + @JsonProperty("naaccr_xml_id") + public String getNaaccrXmlId() { + return _naaccrXmlId; + } + + public void setNaaccrXmlId(String naaccrXmlId) { + _naaccrXmlId = naaccrXmlId; + } + @JsonProperty("default") public String getDefault() { return _default; @@ -142,12 +148,11 @@ public void setUnit(String unit) { } @JsonProperty("metadata") - public Set getMetadata() { + public List getMetadata() { return _metadata; } - @JsonDeserialize(as = LinkedHashSet.class) - public void setMetadata(Set metadata) { + public void setMetadata(List metadata) { _metadata = metadata; } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java index a2ba9e4..245ebc0 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java @@ -3,22 +3,24 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "table"}) +@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "table", "default", "metadata"}) public class StagingSchemaOutput { private String _key; private String _name; private String _description; private Integer _naaccrItem; + private String _naaccrXmlId; private String _table; private String _default; + private List _metadata; - /** - * Morphia requires a default constructor - */ public StagingSchemaOutput() { } @@ -42,8 +44,11 @@ public StagingSchemaOutput(StagingSchemaOutput other) { setName(other.getName()); setDescription(other.getDescription()); setNaaccrItem(other.getNaaccrItem()); + setNaaccrXmlId(other.getNaaccrXmlId()); setTable(other.getTable()); setDefault(other.getDefault()); + if (other.getMetadata() != null) + setMetadata(new ArrayList<>(other.getMetadata())); } @JsonProperty("key") @@ -82,6 +87,15 @@ public void setNaaccrItem(Integer naaccrItem) { _naaccrItem = naaccrItem; } + @JsonProperty("naaccr_xml_id") + public String getNaaccrXmlId() { + return _naaccrXmlId; + } + + public void setNaaccrXmlId(String naaccrXmlId) { + _naaccrXmlId = naaccrXmlId; + } + @JsonProperty("table") public String getTable() { return _table; @@ -100,4 +114,13 @@ public void setDefault(String aDefault) { _default = aDefault; } + @JsonProperty("metadata") + public List getMetadata() { + return _metadata; + } + + public void setMetadata(List metadata) { + _metadata = metadata; + } + } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java index 4986f15..aa44c30 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; +import java.util.Set; import retrofit2.Call; import retrofit2.http.Body; @@ -13,6 +14,9 @@ import retrofit2.http.Path; import retrofit2.http.Query; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; + public interface StagingService { /** @@ -69,6 +73,18 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/schema/{id}") Call schemaById(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id); + /** + * Return a glossary results for a staging schema + * @param algorithm an algorithm identifier + * @param version a version + * @param id a table identifier + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @GET("staging/{algorithm}/{version}/schema/{id}/glossary") + Call> schemaGlossary(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + /** * Return a list of tables which are involved in the specified schema * @param algorithm an algorithm identifier @@ -98,6 +114,17 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/tables") Call> tables(@Path("algorithm") String algorithm, @Path("version") String version, @Query("q") String query); + /** + * Return a list of matching tables + * @param algorithm an algorithm identifier + * @param version a version + * @param query an optional text query + * @param unusedOnly if true, limit to unused tables + * @return a list of staging tables + */ + @GET("staging/{algorithm}/{version}/tables") + Call> tables(@Path("algorithm") String algorithm, @Path("version") String version, @Query("q") String query, @Query("unused") Boolean unusedOnly); + /** * Return a single table definition by table identifier * @param algorithm an algorithm identifier @@ -108,6 +135,18 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/table/{id}") Call tableById(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id); + /** + * Return a glossary results for a staging table + * @param algorithm an algorithm identifier + * @param version a version + * @param id a table identifier + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @GET("staging/{algorithm}/{version}/table/{id}/glossary") + Call> tableGlossary(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + /** * Return a list of schemas which the specified table is involved in * @param algorithm an algorithm identifier diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java index ee48b8f..896c84a 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java @@ -22,17 +22,14 @@ public class StagingTable { private String _subtitle; private String _notes; private String _footnotes; + private String _rationale; + private String additionalInfo; + private String codingGuidelines; private Date _lastModified; private List _definition; private Set _extraInput; private List> _rows; - /** - * Morphia requires a default constructor - */ - public StagingTable() { - } - @JsonProperty("id") public String getId() { return _displayId; @@ -114,6 +111,33 @@ public void setFootnotes(String footnotes) { _footnotes = footnotes; } + @JsonProperty("rationale") + public String getRationale() { + return _rationale; + } + + public void setRationale(String rationale) { + _rationale = rationale; + } + + @JsonProperty("additional_info") + public String getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(String additionalInfo) { + this.additionalInfo = additionalInfo; + } + + @JsonProperty("coding_guidelines") + public String getCodingGuidelines() { + return codingGuidelines; + } + + public void setCodingGuidelines(String codingGuidelines) { + this.codingGuidelines = codingGuidelines; + } + @JsonProperty("last_modified") public Date getLastModified() { return _lastModified; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java index 8b14c3f..0983fa5 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java @@ -19,9 +19,6 @@ public class StagingTablePath { private Set _inputs; private Set _outputs; - /** - * Morphia requires a default constructor - */ public StagingTablePath() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java index c997fd7..99b601c 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java @@ -9,17 +9,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"algorithm", "version", "type", "last_modified"}) +@JsonPropertyOrder({"algorithm", "version", "naaccr_version", "type", "last_modified"}) public class StagingVersion { private String _algorithm; private String _version; + private String _naaccrVersion; private Type _type; private Date _lastModified; - /** - * Default constructor is required by Morphia - */ public StagingVersion() { } @@ -46,6 +44,15 @@ public void setVersion(String version) { _version = version; } + @JsonProperty("naaccr_version") + public String getNaaccrVersion() { + return _naaccrVersion; + } + + public void setNaaccrVersion(String naaccrVersion) { + _naaccrVersion = naaccrVersion; + } + @JsonProperty("type") public Type getType() { return _type; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java index aaf1ba3..eeb3752 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java @@ -8,10 +8,11 @@ import java.util.Set; import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; public class CsSchemaLookup extends SchemaLookup { - private static final Set _ALLOWED_KEYS = new HashSet<>(Arrays.asList(CsStagingData.PRIMARY_SITE_KEY, CsStagingData.HISTOLOGY_KEY, CsStagingData.SSF25_KEY)); + private static final Set _ALLOWED_KEYS = new HashSet<>(Arrays.asList(StagingData.PRIMARY_SITE_KEY, StagingData.HISTOLOGY_KEY, CsStagingData.SSF25_KEY)); /** * Default constructor diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java index d03c180..f6ef98a 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java @@ -57,10 +57,9 @@ public enum CsInput { SSF21("ssf21"), SSF22("ssf22"), SSF23("ssf23"), - SSF24("ssf24"), - SSF25("ssf25"); + SSF24("ssf24"); - private String _name; + private final String _name; CsInput(String name) { _name = name; @@ -116,7 +115,7 @@ public enum CsOutput { STOR_SS1977_STAGE("stor_ss77"), STOR_SS2000_STAGE("stor_ss2000"); - private String _name; + private final String _name; CsOutput(String name) { _name = name; @@ -212,7 +211,7 @@ public void setSsf(Integer id, String ssf) { */ public static class CsStagingInputBuilder { - private CsStagingData _data; + private final CsStagingData _data; public CsStagingInputBuilder() { _data = new CsStagingData(); diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java new file mode 100644 index 0000000..d7806dd --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.eod; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; + +public class EodSchemaLookup extends SchemaLookup { + + private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( + StagingData.PRIMARY_SITE_KEY, + StagingData.HISTOLOGY_KEY, + EodInput.SEX.toString(), + EodInput.DISCRIMINATOR_1.toString(), + EodInput.DISCRIMINATOR_2.toString()))); + + /** + * Constructor + * @param site primary site + * @param histology histology + */ + public EodSchemaLookup(String site, String histology) { + super(site, histology); + } + + @Override + public Set getAllowedKeys() { + return _ALLOWED_KEYS; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java new file mode 100644 index 0000000..afb4f67 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2014 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.eod; + +import com.imsweb.seerapi.client.staging.StagingData; + +public class EodStagingData extends StagingData { + + /** + * Default constructor + */ + public EodStagingData() { + super(); + } + + /** + * Construct with site and histology + * @param site primary site + * @param hist histology + */ + public EodStagingData(String site, String hist) { + super(site, hist); + } + + /** + * Construct with site, histology and discriminators + * @param site primary site + * @param hist histology + * @param discriminator1 first discriminator + */ + public EodStagingData(String site, String hist, String discriminator1) { + super(site, hist); + + setInput(EodInput.DISCRIMINATOR_1, discriminator1); + } + + /** + * Construct with site, histology and discriminators + * @param site primary site + * @param hist histology + * @param discriminator1 first discriminator + * @param discriminator2 second discriminator + */ + public EodStagingData(String site, String hist, String discriminator1, String discriminator2) { + super(site, hist); + + setInput(EodInput.DISCRIMINATOR_1, discriminator1); + setInput(EodInput.DISCRIMINATOR_2, discriminator2); + } + + /** + * Return the specified input value + * @param key input key + * @return input + */ + public String getInput(EodInput key) { + return getInput(key.toString()); + } + + /** + * Set the specified input value + * @param key input key + * @param value value + */ + public void setInput(EodInput key, String value) { + setInput(key.toString(), value); + } + + /** + * Return the specified output value + * @param key output key + * @return output + */ + public String getOutput(EodOutput key) { + return getOutput(key.toString()); + } + + // input key definitions + public enum EodInput { + PRIMARY_SITE("site"), + HISTOLOGY("hist"), + BEHAVIOR("behavior"), + SEX("sex"), + AGE_AT_DX("age_dx"), + DISCRIMINATOR_1("discriminator_1"), + DISCRIMINATOR_2("discriminator_2"), + CLIN_T("clin_t"), + CLIN_T_SUFFIX("clin_t_suffix"), + CLIN_N("clin_n"), + CLIN_N_SUFFIX("clin_n_suffix"), + CLIN_M("clin_m"), + CLIN_STAGE_GROUP_DIRECT("clin_stage_group_direct"), + PATH_T("path_t"), + PATH_T_SUFFIX("path_t_suffix"), + PATH_N("path_n"), + PATH_N_SUFFIX("path_n_suffix"), + PATH_M("path_m"), + PATH_STAGE_GROUP_DIRECT("path_stage_group_direct"), + YPATH_T("ypath_t"), + YPATH_T_SUFFIX("ypath_t_suffix"), + YPATH_N("ypath_n"), + YPATH_N_SUFFIX("ypath_n_suffix"), + YPATH_M("ypath_m"), + YPATH_STAGE_GROUP_DIRECT("ypath_stage_group_direct"), + NODES_POS("nodes_pos"), + NODES_EXAM("nodes_exam"), + EOD_PRIMARY_TUMOR("eod_primary_tumor"), + EOD_REGIONAL_NODES("eod_regional_nodes"), + EOD_METS("eod_mets"), + GRADE_CLIN("grade_clin"), + GRADE_PATH("grade_path"), + GRADE_POST_THERAPY("grade_post_therapy"), + DX_YEAR("year_dx"), + TUMOR_SIZE_CLIN("size_clin"), + TUMOR_SIZE_PATH("size_path"), + TUMOR_SIZE_SUMMARY("size_summary"), + RADIATION_SURG_SEQ("radiation_surg_seq"), + SYSTEMIC_SURG_SEQ("systemic_surg_seq"), + SS_2018("ss2018"); + + private final String _name; + + EodInput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + // output key definitions + public enum EodOutput { + NAACCR_SCHEMA_ID("naaccr_schema_id"), + AJCC_ID("ajcc_id"), + DERIVED_VERSION("derived_version"), + EOD_2018_T("eod_2018_t"), + EOD_2018_N("eod_2018_n"), + EOD_2018_M("eod_2018_m"), + EOD_2018_STAGE_GROUP("eod_2018_stage_group"), + SS_2018_DERIVED("ss2018_derived"); + + private final String _name; + + EodOutput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + /** + * TnmStagingInputBuilder builder + */ + public static class EodStagingInputBuilder { + + private final EodStagingData _data; + + public EodStagingInputBuilder() { + _data = new EodStagingData(); + } + + public EodStagingInputBuilder withDisciminator1(String discriminator1) { + _data.setInput(EodInput.DISCRIMINATOR_1, discriminator1); + return this; + } + + public EodStagingInputBuilder withDisciminator2(String discriminator2) { + _data.setInput(EodInput.DISCRIMINATOR_2, discriminator2); + return this; + } + + public EodStagingInputBuilder withInput(EodInput key, String value) { + _data.setInput(key, value); + return this; + } + + public EodStagingData build() { + return _data; + } + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java new file mode 100644 index 0000000..eac6b13 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.tnm; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; + +public class TnmSchemaLookup extends SchemaLookup { + + private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(StagingData.PRIMARY_SITE_KEY, + StagingData.HISTOLOGY_KEY, TnmStagingData.SSF25_KEY, TnmStagingData.SEX_KEY))); + + /** + * Constructor + * @param site primary site + * @param histology histology + */ + public TnmSchemaLookup(String site, String histology) { + super(site, histology); + } + + @Override + public Set getAllowedKeys() { + return _ALLOWED_KEYS; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java new file mode 100644 index 0000000..e16163c --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2014 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.tnm; + +import com.imsweb.seerapi.client.staging.StagingData; + +public class TnmStagingData extends StagingData { + + // key definitions + public static final String SEX_KEY = "sex"; + public static final String SSF25_KEY = "ssf25"; + + // SSF prefix + public static final String INPUT_SSF_PREFIX = "ssf"; + + // input key definitions + public enum TnmInput { + PRIMARY_SITE("site"), + HISTOLOGY("hist"), + BEHAVIOR("behavior"), + GRADE("grade"), + SEX("sex"), + DX_YEAR("year_dx"), + AGE_AT_DX("age_dx"), + CLIN_STAGE_GROUP_DIRECT("clin_stage_group_direct"), + PATH_STAGE_GROUP_DIRECT("path_stage_group_direct"), + RX_SUMM_SURGERY("systemic_surg_seq"), + RX_SUMM_RADIATION("radiation_surg_seq"), + CLIN_T("clin_t"), + CLIN_N("clin_n"), + CLIN_M("clin_m"), + PATH_T("path_t"), + PATH_N("path_n"), + PATH_M("path_m"), + REGIONAL_NODES_POSITIVE("nodes_pos"), + SSF1("ssf1"), + SSF2("ssf2"), + SSF3("ssf3"), + SSF4("ssf4"), + SSF5("ssf5"), + SSF6("ssf6"), + SSF7("ssf7"), + SSF8("ssf8"), + SSF9("ssf9"), + SSF10("ssf10"), + SSF11("ssf11"), + SSF12("ssf12"), + SSF13("ssf13"), + SSF14("ssf14"), + SSF15("ssf15"), + SSF16("ssf16"), + SSF17("ssf17"), + SSF18("ssf18"), + SSF19("ssf19"), + SSF20("ssf20"), + SSF21("ssf21"), + SSF22("ssf22"), + SSF23("ssf23"), + SSF24("ssf24"); + + private final String _name; + + TnmInput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + // output key definitions + public enum TnmOutput { + DERIVED_VERSION("derived_version"), + CLIN_STAGE_GROUP("clin_stage_group"), + PATH_STAGE_GROUP("path_stage_group"), + COMBINED_STAGE_GROUP("combined_stage_group"), + SOURCE_T("source_t"), + COMBINED_T("combined_t"), + SOURCE_N("source_n"), + COMBINED_N("combined_n"), + SOURCE_M("source_m"), + COMBINED_M("combined_m"); + + private final String _name; + + TnmOutput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + /** + * Default constructor + */ + public TnmStagingData() { + super(); + } + + /** + * Construct with site and histology + * @param site primary site + * @param hist histology + */ + public TnmStagingData(String site, String hist) { + super(site, hist); + } + + /** + * Construct with site, histology and SSF25 + * @param site primary site + * @param hist histology + * @param ssf25 site-specific factor 25 + */ + public TnmStagingData(String site, String hist, String ssf25) { + super(site, hist); + + setSsf(25, ssf25); + } + + /** + * Return the specified input value + * @param key input key + * @return input + */ + public String getInput(TnmInput key) { + return getInput(key.toString()); + } + + /** + * Set the specified input value + * @param key input key + * @param value value + */ + public void setInput(TnmInput key, String value) { + setInput(key.toString(), value); + } + + /** + * Return the specified output value + * @param key output key + * @return output + */ + public String getOutput(TnmOutput key) { + return getOutput(key.toString()); + } + + /** + * Get the specified input site-specific factor + * @param id site-specific factor number + * @return ssf value + */ + public String getSsf(Integer id) { + if (id < 1 || id > 25) + throw new IllegalStateException("Site specific factor must be between 1 and 25."); + + return getInput(INPUT_SSF_PREFIX + id); + } + + /** + * Set the specified input site-specific factor + * @param id site-specific factor number + * @param ssf site-specfic factor value + */ + public void setSsf(Integer id, String ssf) { + if (id < 1 || id > 25) + throw new IllegalStateException("Site specific factor must be between 1 and 25."); + + setInput(INPUT_SSF_PREFIX + id, ssf); + } + + /** + * TnmStagingInputBuilder builder + */ + public static class TnmStagingInputBuilder { + + private final TnmStagingData _data; + + public TnmStagingInputBuilder() { + _data = new TnmStagingData(); + } + + public TnmStagingInputBuilder withSsf(Integer id, String ssf) { + _data.setSsf(id, ssf); + return this; + } + + public TnmStagingInputBuilder withInput(TnmInput key, String value) { + _data.setInput(key, value); + return this; + } + + public TnmStagingData build() { + return _data; + } + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java b/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java index e3fd4d7..4e2dee3 100644 --- a/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java +++ b/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java @@ -10,34 +10,25 @@ import retrofit2.http.Path; import retrofit2.http.Query; -import com.imsweb.seerapi.client.shared.Version; - public interface SurgeryService { /** - * Return a collection of Version objects which describe the available versions - * @return a list of the available site-specific surgery versions and information about each of them - */ - @GET("surgery/versions") - Call> versions(); - - /** - * Return a list of all the site-specific surgery table titles from a specific version - * @param version version + * Return a list of all the site-specific surgery table titles from a specific year + * @param year year * @return a list of site-specific surgery table titles */ - @GET("surgery/{version}/tables") - Call> tables(@Path("version") String version); + @GET("surgery/{year}/tables") + Call> tables(@Path("year") String year); /** - * Return a specific site-specific surgary table from a specific version - * @param version version + * Return a specific site-specific surgary table from a specific year + * @param year year * @param title site title (optional if the site/histology is provided) * @param site primary site (optional if the title is provided) * @param histology histology (optional if the title is provided) * @return a site-specific surgery table */ - @GET("surgery/{version}/table") - Call table(@Path("version") String version, @Query("title") String title, @Query("site") String site, @Query("hist") String histology); + @GET("surgery/{year}/table") + Call table(@Path("year") String year, @Query("title") String title, @Query("site") String site, @Query("hist") String histology); } diff --git a/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java b/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java index 8380b3e..c8fc18f 100644 --- a/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java @@ -3,8 +3,7 @@ import java.io.IOException; import java.util.Collections; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.ObjectMapper; @@ -12,28 +11,32 @@ import com.imsweb.seerapi.client.disease.SiteRange; import com.imsweb.seerapi.client.disease.YearRange; -public class ObjectMapperTest { +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ObjectMapperTest { @Test - public void testMapper() throws IOException { + void testMapper() throws IOException { Range range = new Range("10", "40"); ObjectMapper mapper = SeerApi.getMapper(); String json = mapper.writeValueAsString(range); - Assert.assertTrue(json.contains("low")); - Assert.assertFalse(json.contains("lowValue")); + assertTrue(json.contains("low")); + assertFalse(json.contains("lowValue")); // now test reading that back in range = mapper.readValue(json, Range.class); - Assert.assertEquals("10", range.getLowValue()); - Assert.assertEquals("40", range.getHighValue()); + assertEquals("10", range.getLowValue()); + assertEquals("40", range.getHighValue()); } @Test - public void testDiseaseMapping() throws IOException { + void testDiseaseMapping() throws IOException { Disease partial = new Disease(); partial.setType(Disease.Type.HEMATO); @@ -49,13 +52,13 @@ public void testDiseaseMapping() throws IOException { String json = mapper.writeValueAsString(partial); - Assert.assertTrue(json.contains("icdO3_morphology")); - Assert.assertFalse(json.contains("icdO3Morphology")); + assertTrue(json.contains("icdO3_morphology")); + assertFalse(json.contains("icdO3Morphology")); // now test reading that back in partial = mapper.readValue(json, Disease.class); - Assert.assertEquals("9840/3", partial.getIcdO3Morphology()); + assertEquals("9840/3", partial.getIcdO3Morphology()); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/Range.java b/src/test/java/com/imsweb/seerapi/client/Range.java index 804f745..6cfd17b 100644 --- a/src/test/java/com/imsweb/seerapi/client/Range.java +++ b/src/test/java/com/imsweb/seerapi/client/Range.java @@ -13,6 +13,7 @@ public class Range { protected String _highValue; public Range() { + // the object mapper needs this defined } public Range(String low, String high) { diff --git a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java index e669a9d..48f5ed6 100644 --- a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java +++ b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java @@ -3,20 +3,28 @@ */ package com.imsweb.seerapi.client; -import java.io.IOException; +import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class SeerApiTest { +import retrofit2.Call; - @Test(expected = NotAuthorizedException.class) - public void testBadApiKeyAndURL() throws IOException { - new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().version().execute(); +import com.imsweb.seerapi.client.siterecode.SiteGroupAlgorithm; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class SeerApiTest { + + @Test + void testBadApiKeyAndURL() { + Call> call = new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().algorithms(); + assertThrows(NotAuthorizedException.class, call::execute); } - @Test(expected = NotAuthorizedException.class) - public void testBadApiKey() throws IOException { - new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().version().execute(); + @Test + void testBadApiKey() { + Call> call = new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().algorithms(); + assertThrows(NotAuthorizedException.class, call::execute); } } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 3da3d3b..6efadbb 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -7,71 +7,75 @@ import java.util.Collections; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class DiseaseTest { +class DiseaseTest { private static DiseaseService _DISEASE; - @BeforeClass - public static void setup() { + @BeforeAll + static void setup() { _DISEASE = new SeerApi.Builder().connect().disease(); } @Test - public void testDiseaseTypeCategory() { + void testDiseaseTypeCategory() { assertEquals(Disease.Type.SOLID_TUMOR, Disease.Type.valueOf("SOLID_TUMOR")); } @Test - public void testDiseaseVersions() throws IOException { + void testDiseaseVersions() throws IOException { List versions = _DISEASE.versions().execute().body(); - assertTrue(versions.size() > 0); - for (DiseaseVersion version : versions) { - assertTrue(version.getName().length() > 0); - assertTrue(version.getType().length() > 0); - assertNotNull(version.getLastModified()); - if (version.getName().equals("latest")) { - assertNotNull(version.getType()); - assertNotNull(version.getFirstPublished()); - assertNotNull(version.getCount()); - } - } + assertNotNull(versions); + assertEquals(1, versions.size()); + DiseaseVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type not returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test - public void testDiseasePrimarySites() throws IOException { + void testDiseasePrimarySites() throws IOException { List sites = _DISEASE.primarySites().execute().body(); - assertTrue(sites.size() > 0); + assertNotNull(sites); + assertFalse(sites.isEmpty()); assertEquals("C000", sites.get(0).getValue()); assertEquals("External upper lip", sites.get(0).getLabel()); } @Test - public void testDiseasePrimarySiteCode() throws IOException { + void testDiseasePrimarySiteCode() throws IOException { List sites = _DISEASE.primarySiteCode("C021").execute().body(); - assertTrue(sites.size() > 0); + assertNotNull(sites); + assertFalse(sites.isEmpty()); assertEquals("C021", sites.get(0).getValue()); assertEquals("Border of tongue", sites.get(0).getLabel()); } @Test - public void testDiseaseSiteCateogires() throws IOException { + void testDiseaseSiteCateogires() throws IOException { List categories = _DISEASE.siteCategories().execute().body(); - assertTrue(categories.size() > 0); + assertNotNull(categories); + assertFalse(categories.isEmpty()); assertEquals("head-and-neck", categories.get(0).getId()); assertEquals("Head and Neck", categories.get(0).getLabel()); assertEquals(2, categories.get(0).getSites().size()); @@ -79,15 +83,16 @@ public void testDiseaseSiteCateogires() throws IOException { assertEquals("C148", categories.get(0).getSites().get(0).getHigh()); } + @SuppressWarnings("java:S5961") @Test - public void testDiseaseById() throws IOException { + void testDiseaseById() throws IOException { Disease disease = _DISEASE.getById("latest", "51f6cf58e3e27c3994bd5408").execute().body(); assertNotNull(disease); - assertEquals("Acute erythroid leukemia", disease.getName()); + assertEquals("Pure erythroid leukemia", disease.getName()); assertEquals(Disease.Type.HEMATO, disease.getType()); assertEquals("9840/3", disease.getIcdO3Morphology()); - assertTrue(disease.getSamePrimaries().size() > 0); + assertFalse(disease.getSamePrimaries().isEmpty()); assertNotNull(disease.getId()); assertEquals("latest", disease.getVersion()); @@ -101,16 +106,6 @@ public void testDiseaseById() throws IOException { assertNull(disease.getFieldNotes()); assertNull(disease.getScore()); assertNull(disease.getGlossaryMatches()); - //assertNull(disease.getHistory()); - - // assertTrue(disease.getHistory().size() > 0); - // - // DiseaseHistoryEvent event = disease.getHistory().get(0); - // assertEquals("mayc@imsweb.com", event.getUser()); - // assertNotNull(event.getDate()); - // assertNull(event.getOld()); - // assertNull(event.getNew()); - assertEquals(1, disease.getPrimarySite().size()); assertEquals("C421", disease.getPrimarySite().get(0).getLow()); assertEquals("C421", disease.getPrimarySite().get(0).getHigh()); @@ -121,11 +116,10 @@ public void testDiseaseById() throws IOException { assertEquals(1, disease.getAbstractorNote().size()); assertEquals(2, disease.getTreatment().size()); assertNull(disease.getGenetics()); - assertEquals(12, disease.getAlternateName().size()); - assertEquals("Acute erythremia [OBS]", disease.getAlternateName().get(0).getValue()); - assertTrue(disease.getDefinition().get(0).getValue().startsWith("Acute erythroid leukemia is characterized by a predominant erythroid")); - assertEquals(Collections.singletonList("9840/3"), disease.getIcdO2Morphology()); - assertEquals(Collections.singletonList("9840/3"), disease.getIcdO1Morphology()); + assertFalse(disease.getAlternateName().isEmpty()); + assertEquals("Acute erythemia [OBS]", disease.getAlternateName().get(0).getValue()); + assertTrue(disease.getIcdO2Morphology().contains("9840/3")); + assertTrue(disease.getIcdO1Morphology().contains("9840/3")); assertEquals("C94.0 Acute erythroid leukemia", disease.getIcd10CmCode().get(0).getValue()); assertEquals("C94.0 Acute erythremia and erythroleukemia", disease.getIcd10Code().get(0)); assertEquals("207.0 Acute erythremia and erythroleukemia", disease.getIcd9Code().get(0)); @@ -141,36 +135,48 @@ public void testDiseaseById() throws IOException { assertEquals(1991, disease.getIcdO1Effective().getEndYear().longValue()); assertNull(disease.getMissingPrimarySiteMessage()); assertNull(disease.getGrade()); - assertNull(disease.getTransformFrom()); + assertNotNull(disease.getTransformFrom()); assertNull(disease.getTransformTo()); - assertNull(disease.getImmunophenotype()); + assertNotNull(disease.getImmunophenotype()); assertEquals("Bone marrow biopsy", disease.getDiagnosisMethod().get(0).getValue()); assertEquals("See abstractor notes", disease.getModuleId().get(0).getValue()); assertNull(disease.getBiomarkers()); assertNull(disease.getTreatmentText()); + assertTrue(disease.getDiagnosticConfirmation().get(0).getValue().startsWith("This histology can be determined by positive histology")); } @Test - public void testDiseaseSamePrimary() throws IOException { - SamePrimaries same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010").execute().body(); + void testDiseaseSamePrimary() throws IOException { + SamePrimaries same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010", "2010").execute().body(); assertNotNull(same); - assertEquals(false, same.isSame()); - assertEquals(2010, same.getYear().longValue()); + assertEquals(false, same.getIsSame()); + assertEquals(2010, same.getYear1().longValue()); + assertEquals(2010, same.getYear2().longValue()); + assertEquals("9870/3", same.getDisease1()); + assertEquals("9872/3", same.getDisease2()); + + // try same with different years + same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010", "2015").execute().body(); + + assertNotNull(same); + assertEquals(false, same.getIsSame()); + assertEquals(2010, same.getYear1().longValue()); + assertEquals(2015, same.getYear2().longValue()); assertEquals("9870/3", same.getDisease1()); assertEquals("9872/3", same.getDisease2()); } @Test - public void testDiseaseSearch() throws IOException { + void testDiseaseSearch() throws IOException { DiseaseSearch search = new DiseaseSearch("basophilic", Disease.Type.HEMATO); DiseaseSearchResults results = _DISEASE.search("latest", search.paramMap()).execute().body(); assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(3, results.getTotal().longValue()); - assertEquals(3, results.getResults().size()); + assertEquals(5, results.getTotal().longValue()); + assertEquals(5, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); search.setSiteCategory("BAD_VALUE"); @@ -205,13 +211,13 @@ public void testDiseaseSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(4, results.getTotal().longValue()); - assertEquals(4, results.getResults().size()); + assertEquals(6, results.getTotal().longValue()); + assertEquals(6, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); } @Test - public void testDiseaseSearchIterate() throws IOException { + void testDiseaseSearchIterate() throws IOException { DiseaseSearch search = new DiseaseSearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(100); @@ -223,7 +229,7 @@ public void testDiseaseSearchIterate() throws IOException { DiseaseSearchResults results = _DISEASE.search("latest", search.paramMap()).execute().body(); assertNotNull(results); assertTrue(results.getTotal() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) @@ -234,7 +240,7 @@ public void testDiseaseSearchIterate() throws IOException { } @Test - public void testDiseaseReportability() throws IOException { + void testDiseaseReportability() throws IOException { Disease partial = new Disease(); partial.setType(Disease.Type.HEMATO); @@ -253,7 +259,7 @@ public void testDiseaseReportability() throws IOException { } @Test - public void testDiseaseChangelog() throws IOException { + void testDiseaseChangelog() throws IOException { DiseaseChangelogResults results = _DISEASE.diseaseChangelogs("latest", null, "2013-07-30", 1).execute().body(); assertNotNull(results); @@ -271,10 +277,26 @@ public void testDiseaseChangelog() throws IOException { assertEquals("Initial migration", changelog.getDescription()); DiseaseChangelogEntry entry = changelog.getAdds().get(0); - assertTrue(entry.getId().length() > 0); - assertTrue(entry.getName().length() > 0); + assertFalse(entry.getId().isEmpty()); + assertFalse(entry.getName().isEmpty()); assertNull(entry.getOldVersion()); assertNull(entry.getNewVersion()); } + @Test + void testBeans() { + MatcherAssert.assertThat(Disease.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseSearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseSource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteCategory.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SamePrimaries.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(PrimarySite.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } + } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 5d44360..505c9f7 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -7,122 +7,106 @@ import java.util.Collections; import java.util.EnumSet; import java.util.List; +import java.util.Set; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; +import com.imsweb.seerapi.client.shared.KeywordMatch; -public class GlossaryTest { +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; +import static com.imsweb.seerapi.client.glossary.Glossary.Category.HEMATO; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class GlossaryTest { private static GlossaryService _GLOSSARY; - @BeforeClass - public static void setup() { + @BeforeAll + static void setup() { _GLOSSARY = new SeerApi.Builder().connect().glossary(); } @Test - public void testGlossaryCategory() { - Assert.assertEquals(Glossary.Category.SOLID_TUMOR, Glossary.Category.valueOf("SOLID_TUMOR")); + void testGlossaryCategory() { + assertEquals(Glossary.Category.SOLID_TUMOR, Glossary.Category.valueOf("SOLID_TUMOR")); } @Test - public void testGlossaryVersions() throws IOException { + void testGlossaryVersions() throws IOException { List versions = _GLOSSARY.versions().execute().body(); - Assert.assertTrue(versions.size() > 0); - for (GlossaryVersion version : versions) { - Assert.assertTrue(version.getName().length() > 0); - Assert.assertTrue(version.getType().length() > 0); - Assert.assertNotNull(version.getLastModified()); - } + assertNotNull(versions); + assertEquals(1, versions.size()); + GlossaryVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type isn't returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test - public void testGlossaryById() throws IOException { + void testGlossaryById() throws IOException { GlossarySearchResults results = _GLOSSARY.search("latest", "Lymphangiogram").execute().body(); - Assert.assertTrue(results.getCount() > 0); + assertNotNull(results); + assertTrue(results.getCount() > 0); Glossary glossary = _GLOSSARY.getById("latest", results.getResults().get(0).getId()).execute().body(); - Assert.assertNotNull(glossary); - Assert.assertEquals("Lymphangiogram", glossary.getName()); - Assert.assertEquals(Collections.singletonList(Glossary.Category.GENERAL), glossary.getCategories()); - Assert.assertNull(glossary.getPrimarySite()); - - Assert.assertNull(glossary.getHistology()); - Assert.assertTrue(glossary.getDefinition().startsWith("An x-ray of the lymphatic system.")); - Assert.assertNull(glossary.getAlternateName()); - Assert.assertNull(glossary.getHistory()); - } - - @Test - public void testGlossaryChangelog() throws IOException { - GlossaryChangelogResults results = _GLOSSARY.changelogs("latest", null, null, 1).execute().body(); - - Assert.assertNotNull(results); - - // TODO since all the glossary items were removed from the production database, this needs to be commented out; it will return when they are published again - - /* - Assert.assertEquals(1, changes.size()); - - GlossaryChangelog changelog = changes.get(0); + assertNotNull(glossary); + assertEquals("Lymphangiogram", glossary.getName()); + assertEquals(Collections.singletonList(GENERAL), glossary.getCategories()); + assertNull(glossary.getPrimarySite()); - Assert.assertNotNull(changelog.getUser()); - Assert.assertEquals("latest_dev", changelog.getVersion()); - Assert.assertTrue(changelog.getId().length() > 0); - Assert.assertTrue(changelog.getAdds().size() > 0); - - GlossaryChangelogEntry entry = changelog.getAdds().get(0); - Assert.assertTrue(entry.getId().length() > 0); - Assert.assertTrue(entry.getName().length() > 0); - Assert.assertNull(entry.getOldVersion()); - Assert.assertNull(entry.getNewVersion()); - - Assert.assertNull(changelog.getMods()); - Assert.assertNull(changelog.getDeletes()); - Assert.assertNotNull(changelog.getDate()); - Assert.assertEquals("Initial migration", changelog.getDescription()); - */ + assertNull(glossary.getHistology()); + assertTrue(glossary.getDefinition().startsWith("An x-ray or computer image of the lymphatic system.")); + assertNull(glossary.getAlternateName()); + assertNull(glossary.getHistory()); } @Test - public void testGlossarySearch() throws IOException { + void testGlossarySearch() throws IOException { String term = "killer"; GlossarySearch search = new GlossarySearch(term); GlossarySearchResults results = _GLOSSARY.search("latest", search.paramMap()).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertTrue(results.getTotal().longValue() > 0); - Assert.assertTrue(results.getResults().size() > 0); - Assert.assertEquals(Collections.singletonList(term), results.getTerms()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertTrue(results.getTotal().longValue() > 0); + assertFalse(results.getResults().isEmpty()); + assertEquals(Collections.singletonList(term), results.getTerms()); // add the category and verify there are no results - results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR)).execute().body(); + results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(GENERAL)).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertEquals(0, results.getTotal().longValue()); - Assert.assertNull(results.getResults()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertTrue(results.getTotal().longValue() > 0); + assertFalse(results.getResults().isEmpty()); // add a second category and verify there are we get the results again - results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR, Glossary.Category.HEMATO)).execute().body(); + results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(GENERAL, Glossary.Category.HEMATO)).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertTrue(results.getTotal().longValue() > 0); - Assert.assertTrue(results.getResults().size() > 0); - Assert.assertEquals(Collections.singletonList(term), results.getTerms()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertTrue(results.getTotal().longValue() > 0); + assertFalse(results.getResults().isEmpty()); + assertEquals(Collections.singletonList(term), results.getTerms()); } @Test - public void testGlossarySearchIterate() throws IOException { + void testGlossarySearchIterate() throws IOException { GlossarySearch search = new GlossarySearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(25); @@ -132,9 +116,9 @@ public void testGlossarySearchIterate() throws IOException { while (total == null || search.getOffset() < total) { GlossarySearchResults results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.HEMATO)).execute().body(); - Assert.assertNotNull(results); - Assert.assertTrue(results.getTotal() > 0); - Assert.assertTrue(results.getResults().size() > 0); + assertNotNull(results); + assertTrue(results.getTotal() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) @@ -143,7 +127,36 @@ public void testGlossarySearchIterate() throws IOException { search.setOffset(search.getOffset() + results.getResults().size()); } - Assert.assertTrue(total > 100); + assertTrue(total > 0); + } + + @Test + void testGlossaryMatch() throws IOException { + String text = "white blood cells that produce antibodies"; + + Set matches = _GLOSSARY.match(text, null, true).execute().body(); + assertNotNull(matches); + assertEquals(2, matches.size()); + + matches = _GLOSSARY.match(text, EnumSet.of(GENERAL), true).execute().body(); + assertNotNull(matches); + assertEquals(2, matches.size()); + + matches = _GLOSSARY.match(text, EnumSet.of(HEMATO), true).execute().body(); + assertNotNull(matches); + assertEquals(0, matches.size()); } + @Test + void testBeans() { + MatcherAssert.assertThat(Glossary.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryResource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossarySearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(KeywordMatch.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java new file mode 100644 index 0000000..90b4401 --- /dev/null +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -0,0 +1,112 @@ +package com.imsweb.seerapi.client.hcpcs; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import retrofit2.Response; + +import com.imsweb.seerapi.client.NotFoundException; +import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.hcpcs.Hcpcs.Category; + +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; + +class HcpcsServiceTest { + + private static HcpcsService _HCPCS; + + @BeforeAll + public static void setup() { + _HCPCS = new SeerApi.Builder().connect().hcpcs(); + } + + @Test + void testGetProcedureByCode() throws IOException { + Hcpcs proc = _HCPCS.getProcedure("S0087").execute().body(); + + assertThat(proc).isNotNull(); + assertThat(proc.getHcpcsCode()).isEqualTo("S0087"); + assertThat(proc.getGenericName()).isEqualTo("Alemtuzumab"); + assertThat(proc.getBrandNames()).containsExactly("Campath"); + assertThat(proc.getStrength()).isEqualTo("30 mg"); + assertThat(proc.getFdaApprovalYear()).isEqualTo("2001"); + assertThat(proc.getFdaDiscontinuationYear()).isEqualTo("2012"); + assertThat(proc.getCmsApprovalDate()).isEqualTo("2002-01-01"); + assertThat(proc.getCmsDiscontinuationDate()).isEqualTo("2002-12-31"); + assertThat(proc.getCategories()).containsExactly(Category.IMMUNOTHERAPY); + assertThat(proc.getMajorDrugClass()).isEqualTo("Monoclonal Antibody"); + assertThat(proc.getMinorDrugClass()).isEqualTo("CD52"); + assertThat(proc.getOral()).isFalse(); + assertThat(proc.getDateAdded()).isNotNull(); + assertThat(proc.getDateModified()).isNotNull(); + + assertThatExceptionOfType(NotFoundException.class) + .isThrownBy(() -> _HCPCS.getProcedure("bad_code").execute()) + .withMessage("HCPCS code '%s' does not exist.", "bad_code"); + + // test the new description field and + proc = _HCPCS.getProcedure("G6015").execute().body(); + assertThat(proc).isNotNull(); + assertThat(proc.getDescription()).contains("temporally modulated beams, binary, dynamic mlc, per treatment session"); + + // verify multiple categories are supported + proc = _HCPCS.getProcedure("A9545").execute().body(); + assertThat(proc).isNotNull(); + assertThat(proc.getCategories()).containsExactlyInAnyOrder(Category.IMMUNOTHERAPY, Category.RADIOPHARMACEUTICAL); + + } + + @Test + void testSearch() throws IOException { + Response> response = _HCPCS.search(new HashMap<>()).execute(); + assertThat(response.headers().get("X-Total-Count")).isNotNull(); + assertThat(Integer.valueOf(Objects.requireNonNull(response.headers().get("X-Total-Count")))).isGreaterThan(100); + + List results = response.body(); + assertThat(results).hasSize(25); // default page size is 25 + + Map params = new HashMap<>(); + params.put("page", "2"); + + // test second page + assertThat(_HCPCS.search(params).execute().body()).hasSize(25); + + // test page out of range + params.put("page", "1000"); + assertThat(_HCPCS.search(params).execute().body()).isEmpty(); + + // test searching + params.clear(); + params.put("q", "Ixempra"); + results = _HCPCS.search(params).execute().body(); + assertThat(results).hasSize(2); + assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); + + assertThat(Objects.requireNonNull(results).get(0).getScore()).isPositive(); + + // test categories + params.put("category", Category.CHEMOTHERAPY.toString()); + results = _HCPCS.search(params).execute().body(); + assertThat(results).hasSize(2); + assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); + + params.put("category", Category.IMMUNOTHERAPY.toString()); + assertThat(_HCPCS.search(params).execute().body()).isEmpty(); + } + + @Test + void testBeans() { + MatcherAssert.assertThat(Hcpcs.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } +} \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java similarity index 56% rename from src/test/java/com/imsweb/seerapi/client/mph/MphTest.java rename to src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 8b4f9a6..6149e5e 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -1,33 +1,47 @@ -package com.imsweb.seerapi.client.mph; +package com.imsweb.seerapi.client.hcpcs.mph; import java.io.IOException; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import retrofit2.Call; import com.imsweb.seerapi.client.BadRequestException; import com.imsweb.seerapi.client.SeerApi; -import com.imsweb.seerapi.client.mph.MphInput.HistologyMatchMode; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import com.imsweb.seerapi.client.mph.MphInput; +import com.imsweb.seerapi.client.mph.MphInputPair; +import com.imsweb.seerapi.client.mph.MphOutput; +import com.imsweb.seerapi.client.mph.MphOutput.Result; +import com.imsweb.seerapi.client.mph.MphRule; +import com.imsweb.seerapi.client.mph.MphService; + +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class MphTest { private static MphService _MPH; - @BeforeClass + @BeforeAll public static void setup() { _MPH = new SeerApi.Builder().connect().mph(); } - @Test(expected = BadRequestException.class) - public void testMissingAllInput() throws IOException { - _MPH.mph(new MphInputPair()).execute(); + @Test + void testMissingAllInput() { + Call call = _MPH.mph(new MphInputPair()); + assertThrows(BadRequestException.class, call::execute); } @Test - public void testMissingSite() throws IOException { + void testMissingSite() throws IOException { MphInput input1 = new MphInput(); // site is missing input1.setHistologyIcdO3("8000"); @@ -43,14 +57,12 @@ public void testMissingSite() throws IOException { input2.setLaterality("1"); MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); - assertEquals(MphOutput.Result.QUESTIONABLE, result.getResult()); - assertEquals( - "Unable to identify cancer group for first set of parameters. Valid primary site (C000-C999 excluding C809), histology (8000-9999), behavior (0-3, 6) and diagnosis year are required.", - result.getReason()); + assertNotNull(result); + assertEquals(Result.INVALID_INPUT, result.getResult()); } @Test - public void testResults() throws IOException { + void testResults() throws IOException { MphInput input1 = new MphInput(); input1.setPrimarySite("C509"); input1.setHistologyIcdO3("8000"); @@ -67,8 +79,9 @@ public void testResults() throws IOException { // first test single primary (only differs by site code) MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.SINGLE_PRIMARY, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M13", result.getStep()); assertEquals("Tumors that do not meet any of the criteria are abstracted as a single primary.", result.getReason()); assertEquals(10, result.getAppliedRules().size()); @@ -77,10 +90,11 @@ public void testResults() throws IOException { // next test questionable (setting laterality to unknown for one of the diseases) input2.setLaterality("9"); result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.QUESTIONABLE, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M7", result.getStep()); - assertEquals("Unable to apply Rule M7 of mp_2007_breast. Valid and known laterality should be provided.", result.getReason()); + assertEquals("Unable to apply Rule M7 of MPH 2007-2017 Breast. Valid and known laterality should be provided.", result.getReason()); assertEquals(4, result.getAppliedRules().size()); assertEquals("Is there a tumor(s) in each breast?", result.getAppliedRules().get(3).getQuestion()); @@ -96,16 +110,17 @@ public void testResults() throws IOException { input2.setDateOfDiagnosisYear("1998"); input2.setLaterality("1"); result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M5", result.getStep()); - assertEquals("Tumors diagnosed more than five (5) years apart are multiple primaries.", result.getReason()); + assertEquals("Tumors diagnosed more than 5 years apart are multiple primaries.", result.getReason()); assertEquals(2, result.getAppliedRules().size()); - assertEquals("Are there tumors diagnosed more than five (5) years apart?", result.getAppliedRules().get(1).getQuestion()); + assertEquals("Are there tumors diagnosed more than 5 years apart?", result.getAppliedRules().get(1).getQuestion()); } @Test - public void testLenientMode() throws IOException { + void testLenientMode() throws IOException { MphInput input1 = new MphInput(); MphInput input2 = new MphInput(); input1.setPrimarySite("C502"); @@ -126,21 +141,38 @@ public void testLenientMode() throws IOException { // not passing should default to STRICT MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(9, result.getAppliedRules().size()); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); assertEquals("M12", result.getStep()); + } - // specify STRICT - result = _MPH.mph(new MphInputPair(input1, input2), HistologyMatchMode.STRICT).execute().body(); - assertEquals(9, result.getAppliedRules().size()); - assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); - assertEquals("M12", result.getStep()); + @Test + void testInvalidInput() throws IOException { + MphInput i1 = new MphInput(); + MphInput i2 = new MphInput(); + + // invalid primary site + i1.setPrimarySite("C080"); + i2.setPrimarySite("D080"); + i1.setHistologyIcdO3("8000"); + i1.setBehaviorIcdO3("3"); + i2.setHistologyIcdO3("8100"); + i2.setBehaviorIcdO3("3"); + i1.setDateOfDiagnosisYear("2015"); + i2.setDateOfDiagnosisYear("2015"); + + MphOutput result = _MPH.mph(new MphInputPair(i1, i2)).execute().body(); + assertNotNull(result); + assertEquals(MphOutput.Result.INVALID_INPUT, result.getResult()); + } - // specify LENIENT - result = _MPH.mph(new MphInputPair(input1, input2), HistologyMatchMode.LENIENT).execute().body(); - assertEquals(10, result.getAppliedRules().size()); - assertEquals(MphOutput.Result.SINGLE_PRIMARY, result.getResult()); - assertEquals("M13", result.getStep()); + @Test + void testBeans() { + MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphInputPair.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index bfda340..3a80a40 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -6,72 +6,81 @@ import java.io.IOException; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; -public class NaaccrTest { +class NaaccrTest { private static NaaccrService _NAACCR; - @BeforeClass + @BeforeAll public static void setup() { _NAACCR = new SeerApi.Builder().connect().naaccr(); } @Test - public void testNaaccrVersions() throws IOException { + void testVersions() throws IOException { List versions = _NAACCR.versions().execute().body(); - assertTrue(versions.size() > 0); + assertThat(versions).isNotNull().isNotEmpty(); for (NaaccrVersion version : versions) { - assertTrue(version.getVersion().length() > 0); - assertTrue(version.getName().length() > 0); - assertEquals(22824, version.getLength().longValue()); - assertTrue(version.getDescription().length() > 0); - assertTrue(version.getStyle().length() > 0); + assertThat(version.getVersion()).isNotEmpty(); + assertThat(version.getYearImplemented()).isGreaterThan(2020); + assertThat(version.getDateOfPublication()).isNotNull(); } } @Test - public void testNaaccrFieldNames() throws IOException { - List names = _NAACCR.fieldNames("latest").execute().body(); + void testNaaccrFieldNames() throws IOException { + List names = _NAACCR.fieldNames("latest").execute().body(); - assertTrue(names.size() > 0); - for (NaaccrFieldName name : names) { - assertTrue(name.getItem() > 0); - assertTrue(name.getName().length() > 0); + assertThat(names).isNotNull(); + for (NaaccrItemInfo name : names) { + assertThat(name.getItem()).isNotEmpty(); + assertThat(name.getName()).isNotEmpty(); } } @Test - public void testNaaccrField() throws IOException { - NaaccrField name = _NAACCR.field("latest", 521).execute().body(); - - assertNotNull(name); - assertEquals("Morph--Type&Behav ICD-O-3", name.getName()); - assertEquals("LEFT", name.getAlign()); - assertEquals(" ", name.getPadChar()); - assertTrue(name.getDocumentation().startsWith("")); - assertEquals(521, name.getItem().longValue()); - assertEquals(550, name.getStart().longValue()); - assertEquals(554, name.getEnd().longValue()); - - assertEquals(2, name.getSubFields().size()); - assertEquals(522, name.getSubFields().get(0).getItem().longValue()); - assertEquals(523, name.getSubFields().get(1).getItem().longValue()); + void testNaaccrItem() throws IOException { + validateItem(_NAACCR.item("25", "80").execute().body()); + validateItem(_NAACCR.item("25", "addrAtDxState").execute().body()); + } - NaaccrSubField sub = name.getSubFields().get(0); - assertEquals("Histologic Type ICD-O-3", sub.getName()); - assertEquals(550, sub.getStart().longValue()); - assertEquals(553, sub.getEnd().longValue()); - assertEquals("LEFT", sub.getAlign()); - assertEquals(" ", sub.getPadChar()); + private void validateItem(NaaccrItem item) { + assertThat(item).isNotNull(); + assertThat(item.getItemNumber()).isEqualTo("80"); + assertThat(item.getItemName()).isEqualTo("Addr at DX--State"); + assertThat(item.getItemDataType()).isEqualTo("alpha"); + assertThat(item.getItemLength()).isEqualTo("2"); + assertThat(item.getYearImplemented()).isEqualTo("2011"); + assertThat(item.getVersionImplemented()).isEqualTo("12.2"); + assertThat(item.getXmlNaaccrId()).isEqualTo("addrAtDxState"); + assertThat(item.getXmlParentId()).isEqualTo("Tumor"); + assertThat(item.getRecordTypes()).containsExactlyInAnyOrder("A", "C", "I", "M"); + assertThat(item.getSection()).isEqualTo("Demographic"); + assertThat(item.getSourceOfStandard()).isEqualTo("CoC"); + assertThat(item.getDateCreated()).isInThePast(); + assertThat(item.getDateModified()).isInThePast(); + assertThat(item.getDescription()).isNotEmpty(); + assertThat(item.getRationale()).isNotEmpty(); + assertThat(item.getNpcrCollect()).isEqualTo("Required"); + assertThat(item.getCocCollect()).isEqualTo("Required"); + assertThat(item.getSeerCollect()).isEqualTo("Required"); + assertThat(item.getCccrCollect()).isEqualTo("No recommendation"); + assertThat(item.getAlternateNames()).containsExactlyInAnyOrder("State at Diagnosis (CoC)", "State (pre-96 CoC)"); + assertThat(item.getFormat()).isEqualTo("Upper case"); + assertThat(item.getCodeDescription()).isEqualTo("In addition to USPS abbreviations"); + assertThat(item.getAllowableValues()).isEqualTo("Refer to EDITS table STATE.DBF in Appendix B; CD, US, XX, YY, ZZ"); + assertThat(item.getAllowedCodes()) + .hasSize(5) + .allMatch(allowedCode -> allowedCode.getDescription() != null) + .extracting("code") + .containsExactlyInAnyOrder("CD", "US", "XX", "YY", "ZZ"); } } diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index a03106a..5133619 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -4,71 +4,84 @@ package com.imsweb.seerapi.client.ndc; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import retrofit2.Response; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.ndc.NdcSeerInfo.Category; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.assertj.core.api.Assertions.assertThat; -public class NdcTest { +@SuppressWarnings("ConstantConditions") +class NdcTest { private static NdcService _NDC; - @BeforeClass + @BeforeAll public static void setup() { _NDC = new SeerApi.Builder().connect().ndc(); } @Test - public void testNdcByCode() throws IOException { + void testNdcByCode() throws IOException { NdcProduct product = _NDC.getByCode("0002-3227").execute().body(); - assertNotNull(product); - assertEquals("0002-3227", product.getNdc()); - assertEquals("HUMAN PRESCRIPTION DRUG", product.getTypeName()); - assertEquals("Strattera", product.getProprietaryName()); - assertNull(product.getProprietaryNameSuffix()); - assertEquals(Collections.singletonList("Atomoxetine hydrochloride"), product.getNonProprietaryName()); - assertEquals("CAPSULE", product.getDosageFormName()); - assertEquals(Collections.singletonList("ORAL"), product.getRouteName()); - assertEquals("20021126", product.getStartMarketingDate()); - assertNull(product.getEndMarketingDate()); - assertEquals("NDA", product.getMarketingCategoryName()); - assertEquals("NDA021411", product.getApplicationNumber()); - assertEquals("Eli Lilly and Company", product.getLabelerName()); - assertNull(product.getDeaSchedule()); - assertEquals(1, product.getSubstances().size()); + assertThat(product).isNotNull(); + assertThat(product.getNdc()).isEqualTo("0002-3227"); + assertThat(product.getTypeName()).isEqualTo("HUMAN PRESCRIPTION DRUG"); + assertThat(product.getProprietaryName()).isEqualTo("Strattera"); + assertThat(product.getProprietaryNameSuffix()).isNull(); + assertThat(product.getNonProprietaryName()).containsExactly("Atomoxetine hydrochloride"); + assertThat(product.getDosageFormName()).isEqualTo("CAPSULE"); + assertThat(product.getRouteName()).containsExactly("ORAL"); + assertThat(product.getStartMarketingDate()).isEqualTo("20021126"); + assertThat(product.getEndMarketingDate()).isNull(); + assertThat(product.getMarketingCategoryName()).isEqualTo("NDA"); + assertThat(product.getApplicationNumber()).isEqualTo("NDA021411"); + assertThat(product.getLabelerName()).isEqualTo("Eli Lilly and Company"); + assertThat(product.getDeaSchedule()).isNull(); + assertThat(product.getSubstances()).hasSize(1); NdcSubstance substance = product.getSubstances().get(0); - assertEquals("ATOMOXETINE HYDROCHLORIDE", substance.getName()); - assertEquals("10", substance.getStrengthNumber()); - assertEquals("mg/1", substance.getStrengthUnit()); - - assertEquals(Arrays.asList("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"), product.getPharmClass()); - - assertEquals(2, product.getPackages().size()); - assertEquals("07", product.getPackages().get(0).getCode()); - assertEquals("7 CAPSULE in 1 BOTTLE (0002-3227-07)", product.getPackages().get(0).getDescription()); - assertEquals("30", product.getPackages().get(1).getCode()); - assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(1).getDescription()); - - assertNotNull(product.getDateAdded()); - assertNotNull(product.getDateModified()); - assertNull(product.getDateRemoved()); + assertThat(substance.getName()).isEqualTo("ATOMOXETINE HYDROCHLORIDE"); + assertThat(substance.getStrengthNumber()).isEqualTo("10"); + assertThat(substance.getStrengthUnit()).isEqualTo("mg/1"); + + assertThat(product.getPharmClass()).containsExactly("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"); + + assertThat(product.getPackages()).isNotEmpty(); + assertThat(product.getPackages().get(0).getCode()).isEqualTo("30"); + assertThat(product.getPackages().get(0).getDescription()).isEqualToIgnoringWhitespace("30 CAPSULE in 1 BOTTLE (0002-3227-30)"); + + assertThat(product.getDateAdded()).isNotNull(); + assertThat(product.getDateModified()).isNotNull(); + assertThat(product.getDateRemoved()).isNull(); + + // test one with "seer" added information (0002-4483) + product = _NDC.getByCode("0002-4483").execute().body(); + assertThat(product.getNdc()).isEqualTo("0002-4483"); + assertThat(product.getProprietaryName()).isEqualTo("Verzenio"); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); + assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.CHEMOTHERAPY); + assertThat(product.getSeerInfo().getMajorDrugClass()).contains("Cyclin Dependent"); + assertThat(product.getSeerInfo().getMinorDrugClass()).isEqualTo("CDK 4/6"); + + // the subcategory is being removed but still exists in production; the key should be ignored + product = _NDC.getByCode("0006-0072").execute().body(); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); + assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.ANCILLARY); } @Test - public void testNdcSearch() throws IOException { + void testNdcSearch() throws IOException { NdcSearch search = new NdcSearch(); search.setIncludeRemoved(true); @@ -76,20 +89,18 @@ public void testNdcSearch() throws IOException { // hold onto total number (including "removed") Integer totalIncludingRemoved = Integer.valueOf(response.headers().get("X-Total-Count")); - assertTrue(totalIncludingRemoved > 100000); - - assertEquals(3, response.headers().values("Link").size()); + assertThat(totalIncludingRemoved).isGreaterThan(100000); List products = response.body(); - assertEquals(25, products.size()); + assertThat(products).hasSize(25); search.setQuery("daklinza"); products = _NDC.search(search.paramMap()).execute().body(); - assertTrue(products.size() > 1); + assertThat(products).hasSizeGreaterThan(1); - search.setRemovedSince("2016-07-21"); + search.setRemovedSince("2020-10-01"); products = _NDC.search(search.paramMap()).execute().body(); - assertEquals(0, products.size()); + assertThat(products).isEmpty(); // test removed search = new NdcSearch(); @@ -97,7 +108,57 @@ public void testNdcSearch() throws IOException { response = _NDC.search(search.paramMap()).execute(); Integer totalExcludingRemoved = Integer.valueOf(response.headers().get("X-Total-Count")); - assertTrue(totalIncludingRemoved > totalExcludingRemoved); + assertThat(totalIncludingRemoved).isGreaterThan(totalExcludingRemoved); + } + + @Test + void testNdcSearchByCategory() throws IOException { + NdcSearch search = new NdcSearch(); + search.setCategory(Category.CHEMOTHERAPY); + + Response> response = _NDC.search(search.paramMap()).execute(); + + assertThat(Integer.valueOf(response.headers().get("X-Total-Count"))).isPositive(); + + List products = response.body(); + assertThat(products).isNotEmpty(); + + NdcProduct product = products.get(0); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); + assertThat(product.getSeerInfo().getCategories()).contains(Category.CHEMOTHERAPY); } + @Test + void testNdcHasSeerInfo() throws IOException { + NdcSearch search = new NdcSearch(); + search.setIncludeRemoved(true); + + // get count of all drugs + Response> response = _NDC.search(search.paramMap()).execute(); + Integer totalCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(totalCount).isPositive(); + + // get count of seer-info drugs + search.setHasSeerInfo(true); + response = _NDC.search(search.paramMap()).execute(); + Integer withCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(withCount).isPositive().isLessThan(totalCount); + + // get count of non seer-info drugs + search.setHasSeerInfo(false); + response = _NDC.search(search.paramMap()).execute(); + Integer withoutCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(withCount).isPositive().isLessThan(totalCount); + + assertThat(totalCount).isEqualTo(withCount + withoutCount); + } + + @Test + void testBeans() { + MatcherAssert.assertThat(NdcProduct.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcPackage.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcSubstance.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcSearch.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcSeerInfo.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index ae73f2a..f2029c9 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -9,53 +9,59 @@ import java.util.HashSet; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class RxTest { +class RxTest { private static RxService _RX; - @BeforeClass - public static void setup() { + @BeforeAll + static void setup() { _RX = new SeerApi.Builder().connect().rx(); } @Test - public void testRxVersions() throws IOException { + void testRxVersions() throws IOException { List versions = _RX.versions().execute().body(); - assertTrue(versions.size() > 0); - for (RxVersion version : versions) { - assertTrue(version.getName().length() > 0); - assertTrue(version.getType().length() > 0); - assertNotNull(version.getLastModified()); - } + assertNotNull(versions); + assertEquals(1, versions.size()); + RxVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type not returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test - public void testRxById() throws IOException { - Rx rx = _RX.getById("latest", "53c44afe102c1290262dc672").execute().body(); + void testRxById() throws IOException { + Rx rx = _RX.getById("latest", "53c44b0a102c1290262dce76").execute().body(); assertNotNull(rx); - assertEquals("ABT-751", rx.getName()); + assertEquals("Imatinib mesylate", rx.getName()); assertTrue(rx.getAlternateName().size() > 1); assertEquals(Rx.Type.DRUG, rx.getType()); assertNull(rx.getHistology()); - assertTrue(rx.getRemarks().startsWith("Phase II ALL")); + assertTrue(rx.getRemarks().startsWith("January 31, 2012")); assertNull(rx.getEvsId()); assertNull(rx.getAbbreviation()); assertEquals(Collections.singletonList("Chemotherapy"), rx.getCategory()); - assertTrue(rx.getSubcategory().size() > 0); - assertNull(rx.getNscNumber()); + assertFalse(rx.getSubcategory().isEmpty()); + assertEquals(1, rx.getNscNumber().size()); assertNull(rx.getDrugs()); assertNull(rx.getRadiation()); assertNull(rx.getHidden()); @@ -67,12 +73,22 @@ public void testRxById() throws IOException { assertNull(rx.getNote()); assertNull(rx.getFieldNotes()); assertNull(rx.getScore()); - assertEquals(Arrays.asList("neuroblastoma", "Pediatric ALL"), rx.getPrimarySite()); + assertEquals(Arrays.asList("aggressive mastocytosis", + "chronic eosinophilic leukemia", + "Colorectal", + "dermatofibrosarcoma protuberans", + "gastric", + "GIST", + "hypereosinophilic syndrome", + "leukemia", + "lung", + "other cancer", + "Ph+ALL"), rx.getPrimarySite()); assertNull(rx.getHistory()); } @Test - public void testRxChangelog() throws IOException { + void testRxChangelog() throws IOException { RxChangelogResults results = _RX.changelogs("latest", "2015-08-30", "2015-09-30", 1).execute().body(); assertNotNull(results); @@ -88,20 +104,20 @@ public void testRxChangelog() throws IOException { assertNotNull(changelog.getUser()); assertEquals("latest", changelog.getVersion()); assertNull(changelog.getAdds()); - assertTrue(changelog.getMods().size() > 0); + assertFalse(changelog.getMods().isEmpty()); assertNull(changelog.getDeletes()); assertNotNull(changelog.getDate()); assertNull(changelog.getDescription()); RxChangelogEntry entry = changelog.getMods().get(0); - assertTrue(entry.getId().length() > 0); - assertTrue(entry.getName().length() > 0); + assertFalse(entry.getId().isEmpty()); + assertFalse(entry.getName().isEmpty()); assertNotNull(entry.getOldVersion()); assertNotNull(entry.getNewVersion()); } @Test - public void testRxSearch() throws IOException { + void testRxSearch() throws IOException { RxSearch search = new RxSearch("abt", Rx.Type.DRUG); RxSearchResults results = _RX.search("latest", search.paramMap()).execute().body(); @@ -132,7 +148,7 @@ public void testRxSearch() throws IOException { } @Test - public void testRxSearchIterate() throws IOException { + void testRxSearchIterate() throws IOException { RxSearch search = new RxSearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(100); @@ -144,7 +160,7 @@ public void testRxSearchIterate() throws IOException { RxSearchResults results = _RX.search("latest", search.paramMap()).execute().body(); assertNotNull(results); assertTrue(results.getTotal() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) @@ -153,4 +169,15 @@ public void testRxSearchIterate() throws IOException { search.setOffset(search.getOffset() + results.getResults().size()); } } + + @Test + void testBeans() { + MatcherAssert.assertThat(Rx.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxSearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } } diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index a056702..00e7137 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -4,9 +4,12 @@ package com.imsweb.seerapi.client.siterecode; import java.io.IOException; +import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import retrofit2.Call; @@ -14,59 +17,80 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.shared.Version; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class SiteRecodeTest { private static SiteRecodeService _SITE_RECODE; - @BeforeClass + @BeforeAll public static void setup() { _SITE_RECODE = new SeerApi.Builder().connect().siteRecode(); } - @Test(expected = BadRequestException.class) - public void testBadRequestExceptiion() throws IOException { - _SITE_RECODE.siteGroup("C379", null).execute(); + @Test + void testBadRequestException() { + Call call = _SITE_RECODE.siteGroup("seer", "C379", null, null); + assertThrows(BadRequestException.class, call::execute); + } + + @Test + void testSiteRecodeAlgorithms() throws IOException { + List algorithms = _SITE_RECODE.algorithms().execute().body(); + + assertNotNull(algorithms); + assertEquals(3, algorithms.size()); } @Test - public void testExceptionMessages() throws IOException { + void testExceptionMessages() throws IOException { String message = ""; try { - _SITE_RECODE.siteGroup("C379", null).execute(); + _SITE_RECODE.siteGroup("seer", "C379", null, null).execute(); } catch (BadRequestException e) { message = e.getMessage(); } // the API call works out to: - // https://api.seer.cancer.gov/rest/recode/sitegroup?site=C379 - // and the full message returned should be - // {"code":400,"message":"Site and histology must be supplied"} - assertEquals("Site and histology must be supplied", message); - } - - @Test - public void testSiteRecordVersion() throws IOException { - Call call = _SITE_RECODE.version(); - String version = call.execute().body().getVersion(); - - assertNotNull(version); - assertTrue(version.length() > 0); + // https://api.seer.cancer.gov/rest/recode/sitegroup/seer?site=C379 + assertEquals("Required parameter 'hist' is not present.", message); } @Test - public void testSiteRecode() throws IOException { - Call call = _SITE_RECODE.siteGroup("C379", "9650"); + void testSiteRecode() throws IOException { + Call call = _SITE_RECODE.siteGroup("seer", "C379", "9650", null); SiteRecode recode = call.execute().body(); + assertNotNull(recode); assertEquals("C379", recode.getSite()); assertEquals("9650", recode.getHist()); assertEquals("33011", recode.getSiteGroup()); + + call = _SITE_RECODE.siteGroup("iccc", "C379", "9650", "3"); + recode = call.execute().body(); + assertNotNull(recode); + assertEquals("C379", recode.getSite()); + assertEquals("9650", recode.getHist()); + assertEquals("021", recode.getSiteGroup()); + + call = _SITE_RECODE.siteGroup("aya", "C379", "9650", "3"); + recode = call.execute().body(); + assertNotNull(recode); + assertEquals("C379", recode.getSite()); + assertEquals("9650", recode.getHist()); + assertEquals("06", recode.getSiteGroup()); + } + + @Test + void testBeans() { + MatcherAssert.assertThat(Version.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteRecode.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 87d80fa..97e2ac9 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -4,201 +4,522 @@ package com.imsweb.seerapi.client.staging; import java.io.IOException; +import java.util.EnumSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.disease.DateRange; +import com.imsweb.seerapi.client.disease.DateRangeString; +import com.imsweb.seerapi.client.disease.YearRange; +import com.imsweb.seerapi.client.disease.YearRangeInteger; +import com.imsweb.seerapi.client.disease.YearRangeString; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class StagingTest { +import com.imsweb.seerapi.client.staging.cs.CsStagingData; +import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsInput; +import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsStagingInputBuilder; +import com.imsweb.seerapi.client.staging.eod.EodSchemaLookup; +import com.imsweb.seerapi.client.staging.eod.EodStagingData; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodOutput; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodStagingInputBuilder; +import com.imsweb.seerapi.client.staging.tnm.TnmSchemaLookup; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmInput; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmOutput; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmStagingInputBuilder; + +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanEquals; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSettersExcluding; +import static com.imsweb.seerapi.client.staging.StagingData.HISTOLOGY_KEY; +import static com.imsweb.seerapi.client.staging.StagingData.PRIMARY_SITE_KEY; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.CSVER_DERIVED; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SCHEMA_NUMBER; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS1977_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS2000_STAGE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +class StagingTest { private static final String _ALGORITHM = "cs"; private static final String _VERSION = "02.05.50"; private static StagingService _STAGING; - @BeforeClass - public static void setup() { + @BeforeAll + static void setup() { _STAGING = new SeerApi.Builder().connect().staging(); } @Test - public void testGetAlgorithms() throws IOException { + void testGetAlgorithms() throws IOException { List algorithms = _STAGING.algorithms().execute().body(); - assertTrue(algorithms.size() > 0); + assertThat(algorithms).isNotEmpty().extracting("algorithm").contains("cs", "tnm", "eod_public"); } @Test - public void testGetAlgorithmVersions() throws IOException { + void testGetAlgorithmVersions() throws IOException { List versions = _STAGING.versions(_ALGORITHM).execute().body(); - assertTrue(versions.size() > 0); + assertThat(versions).isNotEmpty(); } @Test - public void testListSchemas() throws IOException { + void testListSchemas() throws IOException { List schemaInfos = _STAGING.schemas(_ALGORITHM, _VERSION).execute().body(); - assertTrue(schemaInfos.size() > 0); + assertThat(schemaInfos).isNotEmpty(); schemaInfos = _STAGING.schemas(_ALGORITHM, _VERSION, "skin").execute().body(); - assertTrue(schemaInfos.size() > 0); + assertThat(schemaInfos).isNotEmpty(); } @Test - public void testSchemaLookup() throws IOException { + void testSchemaLookup() throws IOException { // first test simple lookup that returns a single schema with site/hist only List schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C509", "8000").getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("breast", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("breast"); // now test just site SchemaLookup data = new SchemaLookup(); - data.setInput(StagingData.PRIMARY_SITE_KEY, "C111"); - assertEquals(7, _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body().size()); + data.setInput(PRIMARY_SITE_KEY, "C111"); + assertThat(_STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body()).hasSize(7); // add histology data.setInput(StagingData.HISTOLOGY_KEY, "8000"); - assertEquals(2, _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body().size()); + assertThat(_STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body()).hasSize(2); // add discriminator data.setInput("ssf25", "010"); schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("nasopharynx", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); - // test with the CsStaging class + // test with the CS schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C111", "8000", "010").getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("nasopharynx", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); + + // test with the TNM + schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new TnmSchemaLookup("C680", "8000").getInputs()).execute().body(); + assertThat(schemas).hasSize(1).extracting("id").contains("urethra"); + + // test with the EOD + schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new EodSchemaLookup("C680", "8000").getInputs()).execute().body(); + assertThat(schemas).hasSize(1).extracting("id").contains("urethra"); + + Map values = new HashMap<>(); + values.put(PRIMARY_SITE_KEY, "C680"); + values.put(HISTOLOGY_KEY, "8000"); + SchemaLookup schemaLookup = new SchemaLookup(values); + assertThat(schemaLookup.getInput(PRIMARY_SITE_KEY)).isEqualTo("C680"); + assertThat(schemaLookup.getSite()).isEqualTo("C680"); + assertThat(schemaLookup.getHistology()).isEqualTo("8000"); + assertThat(schemaLookup.hasDiscriminator()).isFalse(); + + assertThat(schemaLookup).isEqualTo(new SchemaLookup("C680", "8000")); + + // test invalid input + CsSchemaLookup csLookup = new CsSchemaLookup(); + csLookup.setSite("C111"); + csLookup.setHistology("8000"); + csLookup.setInput(CsStagingData.SSF25_KEY, "010"); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> csLookup.setInput("bad_key", "1")) + .withMessageContaining("is not allowed for lookups"); + assertThat(csLookup.hasDiscriminator()).isTrue(); + + // test clearning inpuyts + schemaLookup.clearInputs(); + assertThat(schemaLookup.getInput(PRIMARY_SITE_KEY)).isNull(); } @Test - public void testSchemaById() throws IOException { + void testSchemaById() throws IOException { StagingSchema schema = _STAGING.schemaById(_ALGORITHM, _VERSION, "brain").execute().body(); - assertEquals("cs", schema.getAlgorithm()); - assertEquals("02.05.50", schema.getVersion()); - assertEquals("brain", schema.getId()); + assertThat(schema).isNotNull(); + assertThat(schema.getAlgorithm()).isEqualTo("cs"); + assertThat(schema.getVersion()).isEqualTo("02.05.50"); + assertThat(schema.getId()).isEqualTo("brain"); + + // verify the inputs + StagingSchemaInput input = schema.getInputs().stream().filter(i -> "site".equals(i.getKey())).findFirst().orElse(null); + assertThat(input).isNotNull(); + assertThat(input.getName()).isEqualTo("Primary Site"); + assertThat(input.getDescription()).isEqualTo("Code for the primary site of the tumor being reported using either ICD-O-2 or ICD-O-3."); + assertThat(input.getNaaccrItem()).isEqualTo(400); + assertThat(input.getNaaccrXmlId()).isEqualTo("primarySite"); + assertThat(input.getUsedForStaging()).isTrue(); + assertThat(input.getTable()).isEqualTo("primary_site"); + + // verify the outputs + StagingSchemaOutput output = schema.getOutputs().stream().filter(i -> "csver_derived".equals(i.getKey())).findFirst().orElse(null); + assertThat(output).isNotNull(); + assertThat(output.getName()).isEqualTo("CS Version Derived"); + assertThat(output.getDescription()).isEqualTo("Collaborative Staging (CS) version used to derive the CS output fields."); + assertThat(output.getNaaccrItem()).isEqualTo(2936); + assertThat(output.getNaaccrXmlId()).isEqualTo("csVersionDerived"); + assertThat(output.getDefault()).isEqualTo("020550"); } @Test - public void testSchemaInvolvedTables() throws IOException { + void testSchemaInvolvedTables() throws IOException { List tables = _STAGING.involvedTables(_ALGORITHM, _VERSION, "brain").execute().body(); - assertTrue(tables.size() > 0); + assertThat(tables).isNotEmpty(); } @Test - public void testListTables() throws IOException { + void testListTables() throws IOException { List tables = _STAGING.tables(_ALGORITHM, _VERSION, "ssf1").execute().body(); + assertThat(tables).isNotEmpty(); - assertTrue(tables.size() > 0); + tables = _STAGING.tables(_ALGORITHM, _VERSION, null, true).execute().body(); + assertThat(tables).isEmpty(); + tables = _STAGING.tables(_ALGORITHM, _VERSION, null, false).execute().body(); + assertThat(tables).isNotEmpty(); } @Test - public void testTableById() throws IOException { + void testTableById() throws IOException { StagingTable table = _STAGING.tableById(_ALGORITHM, _VERSION, "primary_site").execute().body(); - assertEquals("cs", table.getAlgorithm()); - assertEquals("02.05.50", table.getVersion()); - assertEquals("primary_site", table.getId()); + assertThat(table).isNotNull(); + assertThat(table.getAlgorithm()).isEqualTo("cs"); + assertThat(table.getVersion()).isEqualTo("02.05.50"); + assertThat(table.getId()).isEqualTo("primary_site"); } @Test - public void testTableInvoledSchemas() throws IOException { + void testTableInvoledSchemas() throws IOException { List schemas = _STAGING.involvedSchemas(_ALGORITHM, _VERSION, "extension_baa").execute().body(); - assertTrue(schemas.size() > 0); + assertThat(schemas).isNotEmpty(); } @Test - public void testStaging() throws IOException { - // test this case: http://seer.cancer.gov/seertools/cstest/?mets=10&lnexam=99&diagnosis_year=2013&grade=9&exteval=9&age=060&site=C680&metseval=9&hist=8000&ext=100&version=020550&nodeseval=9&behav=3&lnpos=99&nodes=100&csver_original=020440&lvi=9&ssf1=020&size=075 - StagingData data = new StagingData(); - data.setInput("site", "C680"); - data.setInput("hist", "8000"); - data.setInput("behavior", "3"); - data.setInput("grade", "9"); - data.setInput("year_dx", "2013"); - data.setInput("cs_input_version_original", "020550"); - data.setInput("size", "075"); - data.setInput("extension", "100"); - data.setInput("extension_eval", "9"); - data.setInput("nodes", "100"); - data.setInput("nodes_eval", "9"); - data.setInput("nodes_pos", "99"); - data.setInput("nodes_exam", "99"); - data.setInput("mets", "10"); - data.setInput("mets_eval", "9"); - data.setInput("lvi", "9"); - data.setInput("age_dx", "060"); - data.setInput("ssf1", "020"); + void testCsInputBuilder() { + CsStagingData data1 = new CsStagingData(); + data1.setInput(CsInput.PRIMARY_SITE, "C680"); + data1.setInput(CsInput.HISTOLOGY, "8000"); + data1.setInput(CsInput.BEHAVIOR, "3"); + data1.setInput(CsInput.GRADE, "9"); + data1.setInput(CsInput.DX_YEAR, "2013"); + data1.setInput(CsInput.CS_VERSION_ORIGINAL, "020550"); + data1.setInput(CsInput.TUMOR_SIZE, "075"); + data1.setInput(CsInput.EXTENSION, "100"); + data1.setInput(CsInput.EXTENSION_EVAL, "9"); + data1.setInput(CsInput.LYMPH_NODES, "100"); + data1.setInput(CsInput.LYMPH_NODES_EVAL, "9"); + data1.setInput(CsInput.REGIONAL_NODES_POSITIVE, "99"); + data1.setInput(CsInput.REGIONAL_NODES_EXAMINED, "99"); + data1.setInput(CsInput.METS_AT_DX, "10"); + data1.setInput(CsInput.METS_EVAL, "9"); + data1.setInput(CsInput.LVI, "9"); + data1.setInput(CsInput.AGE_AT_DX, "060"); + data1.setSsf(1, "020"); + + CsStagingData data2 = new CsStagingInputBuilder() + .withInput(CsStagingData.CsInput.PRIMARY_SITE, "C680") + .withInput(CsStagingData.CsInput.HISTOLOGY, "8000") + .withInput(CsStagingData.CsInput.BEHAVIOR, "3") + .withInput(CsStagingData.CsInput.GRADE, "9") + .withInput(CsStagingData.CsInput.DX_YEAR, "2013") + .withInput(CsStagingData.CsInput.CS_VERSION_ORIGINAL, "020550") + .withInput(CsStagingData.CsInput.TUMOR_SIZE, "075") + .withInput(CsStagingData.CsInput.EXTENSION, "100") + .withInput(CsStagingData.CsInput.EXTENSION_EVAL, "9") + .withInput(CsStagingData.CsInput.LYMPH_NODES, "100") + .withInput(CsStagingData.CsInput.LYMPH_NODES_EVAL, "9") + .withInput(CsStagingData.CsInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(CsStagingData.CsInput.REGIONAL_NODES_EXAMINED, "99") + .withInput(CsStagingData.CsInput.METS_AT_DX, "10") + .withInput(CsStagingData.CsInput.METS_EVAL, "9") + .withInput(CsStagingData.CsInput.LVI, "9") + .withInput(CsStagingData.CsInput.AGE_AT_DX, "060") + .withSsf(1, "020") + .build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); + } + + @Test + void testCsStaging() throws IOException { + CsStagingData data = new CsStagingInputBuilder() + .withInput(CsInput.PRIMARY_SITE, "C680") + .withInput(CsInput.HISTOLOGY, "8000") + .withInput(CsInput.BEHAVIOR, "3") + .withInput(CsInput.GRADE, "9") + .withInput(CsInput.DX_YEAR, "2013") + .withInput(CsInput.CS_VERSION_ORIGINAL, "020550") + .withInput(CsInput.TUMOR_SIZE, "075") + .withInput(CsInput.EXTENSION, "100") + .withInput(CsInput.EXTENSION_EVAL, "9") + .withInput(CsInput.LYMPH_NODES, "100") + .withInput(CsInput.LYMPH_NODES_EVAL, "9") + .withInput(CsInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(CsInput.REGIONAL_NODES_EXAMINED, "99") + .withInput(CsInput.METS_AT_DX, "10") + .withInput(CsInput.METS_EVAL, "9") + .withInput(CsInput.LVI, "9") + .withInput(CsInput.AGE_AT_DX, "060") + .withSsf(1, "020") + .build(); // perform the staging - StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); + StagingData output = _STAGING.stage("cs", "02.05.50", data.getInput()).execute().body(); - assertEquals(StagingData.Result.STAGED, output.getResult()); - assertEquals(0, output.getErrors().size()); - assertEquals(37, output.getPath().size()); + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(37); // check output - assertEquals("129", output.getOutput("schema_number")); - assertEquals("urethra", output.getSchemaId()); - assertEquals("020550", output.getOutput("csver_derived")); + assertThat(output.getOutput(SCHEMA_NUMBER.toString())).isEqualTo("129"); + assertThat(output.getSchemaId()).isEqualTo("urethra"); + assertThat(output.getOutput(CSVER_DERIVED.toString())).isEqualTo("020550"); // AJCC 6 - assertEquals("T1", output.getOutput("ajcc6_t")); - assertEquals("10", output.getOutput("stor_ajcc6_t")); - assertEquals("c", output.getOutput("ajcc6_tdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_tdescriptor")); - assertEquals("N1", output.getOutput("ajcc6_n")); - assertEquals("10", output.getOutput("stor_ajcc6_n")); - assertEquals("c", output.getOutput("ajcc6_ndescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_ndescriptor")); - assertEquals("M1", output.getOutput("ajcc6_m")); - assertEquals("10", output.getOutput("stor_ajcc6_m")); - assertEquals("c", output.getOutput("ajcc6_mdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_mdescriptor")); - assertEquals("IV", output.getOutput("ajcc6_stage")); - assertEquals("70", output.getOutput("stor_ajcc6_stage")); + assertThat(output.getOutput(AJCC6_T.toString())).isEqualTo("T1"); + assertThat(output.getOutput(STOR_AJCC6_T.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(STOR_AJCC6_N.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(STOR_AJCC6_M.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_STAGE.toString())).isEqualTo("IV"); + assertThat(output.getOutput(STOR_AJCC6_STAGE.toString())).isEqualTo("70"); // AJCC 7 - assertEquals("T1", output.getOutput("ajcc7_t")); - assertEquals("100", output.getOutput("stor_ajcc7_t")); - assertEquals("c", output.getOutput("ajcc7_tdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_tdescriptor")); - assertEquals("N1", output.getOutput("ajcc7_n")); - assertEquals("100", output.getOutput("stor_ajcc7_n")); - assertEquals("c", output.getOutput("ajcc7_ndescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_ndescriptor")); - assertEquals("M1", output.getOutput("ajcc7_m")); - assertEquals("100", output.getOutput("stor_ajcc7_m")); - assertEquals("c", output.getOutput("ajcc7_mdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_mdescriptor")); - assertEquals("IV", output.getOutput("ajcc7_stage")); - assertEquals("700", output.getOutput("stor_ajcc7_stage")); + assertThat(output.getOutput(AJCC7_T.toString())).isEqualTo("T1"); + assertThat(output.getOutput(STOR_AJCC7_T.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(STOR_AJCC7_N.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(STOR_AJCC7_M.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_STAGE.toString())).isEqualTo("IV"); + assertThat(output.getOutput(STOR_AJCC7_STAGE.toString())).isEqualTo("700"); // Summary Stage - assertEquals("L", output.getOutput("t77")); - assertEquals("RN", output.getOutput("n77")); - assertEquals("D", output.getOutput("m77")); - assertEquals("D", output.getOutput("ss77")); - assertEquals("7", output.getOutput("stor_ss77")); - assertEquals("L", output.getOutput("t2000")); - assertEquals("RN", output.getOutput("n2000")); - assertEquals("D", output.getOutput("m2000")); - assertEquals("D", output.getOutput("ss2000")); - assertEquals("7", output.getOutput("stor_ss2000")); + assertThat(output.getOutput(SS1977_T.toString())).isEqualTo("L"); + assertThat(output.getOutput(SS1977_N.toString())).isEqualTo("RN"); + assertThat(output.getOutput(SS1977_M.toString())).isEqualTo("D"); + assertThat(output.getOutput(SS1977_STAGE.toString())).isEqualTo("D"); + assertThat(output.getOutput(STOR_SS1977_STAGE.toString())).isEqualTo("7"); + assertThat(output.getOutput(SS2000_T.toString())).isEqualTo("L"); + assertThat(output.getOutput(SS2000_N.toString())).isEqualTo("RN"); + assertThat(output.getOutput(SS2000_M.toString())).isEqualTo("D"); + assertThat(output.getOutput(SS2000_STAGE.toString())).isEqualTo("D"); + assertThat(output.getOutput(STOR_SS2000_STAGE.toString())).isEqualTo("7"); + } + + @Test + void testTnmInputBuilder() { + TnmStagingData data1 = new TnmStagingData(); + data1.setInput(TnmInput.PRIMARY_SITE, "C680"); + data1.setInput(TnmInput.HISTOLOGY, "8000"); + data1.setInput(TnmInput.BEHAVIOR, "3"); + data1.setInput(TnmInput.GRADE, "9"); + data1.setInput(TnmInput.DX_YEAR, "2013"); + data1.setInput(TnmInput.REGIONAL_NODES_POSITIVE, "99"); + data1.setInput(TnmInput.AGE_AT_DX, "060"); + data1.setInput(TnmInput.SEX, "1"); + data1.setInput(TnmInput.RX_SUMM_SURGERY, "8"); + data1.setInput(TnmInput.RX_SUMM_RADIATION, "9"); + data1.setInput(TnmInput.CLIN_T, "1"); + data1.setInput(TnmInput.CLIN_N, "2"); + data1.setInput(TnmInput.CLIN_M, "3"); + data1.setInput(TnmInput.PATH_T, "4"); + data1.setInput(TnmInput.PATH_N, "5"); + data1.setInput(TnmInput.PATH_M, "6"); + data1.setSsf(1, "020"); + + TnmStagingData data2 = new TnmStagingData.TnmStagingInputBuilder() + .withInput(TnmInput.PRIMARY_SITE, "C680") + .withInput(TnmInput.HISTOLOGY, "8000") + .withInput(TnmInput.BEHAVIOR, "3") + .withInput(TnmInput.GRADE, "9") + .withInput(TnmInput.DX_YEAR, "2013") + .withInput(TnmInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(TnmInput.AGE_AT_DX, "060") + .withInput(TnmInput.SEX, "1") + .withInput(TnmInput.RX_SUMM_SURGERY, "8") + .withInput(TnmInput.RX_SUMM_RADIATION, "9") + .withInput(TnmInput.CLIN_T, "1") + .withInput(TnmInput.CLIN_N, "2") + .withInput(TnmInput.CLIN_M, "3") + .withInput(TnmInput.PATH_T, "4") + .withInput(TnmInput.PATH_N, "5") + .withInput(TnmInput.PATH_M, "6") + .withSsf(1, "020").build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); + } + + @Test + void testTnmStaging() throws IOException { + TnmStagingData data = new TnmStagingInputBuilder() + .withInput(TnmInput.PRIMARY_SITE, "C680") + .withInput(TnmInput.HISTOLOGY, "8000") + .withInput(TnmInput.BEHAVIOR, "3") + .withInput(TnmInput.DX_YEAR, "2016") + .withInput(TnmInput.RX_SUMM_SURGERY, "2") + .withInput(TnmInput.RX_SUMM_RADIATION, "4") + .withInput(TnmInput.REGIONAL_NODES_POSITIVE, "02") + .withInput(TnmInput.CLIN_T, "c0") + .withInput(TnmInput.CLIN_N, "c1") + .withInput(TnmInput.CLIN_M, "c0") + .withInput(TnmInput.PATH_T, "p0") + .withInput(TnmInput.PATH_N, "p1") + .withInput(TnmInput.PATH_M, "p1") + .build(); + + // perform the staging + StagingData output = _STAGING.stage("tnm", "1.9", data.getInput()).execute().body(); + + // check output + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getSchemaId()).isEqualTo("urethra"); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(25); + assertThat(output.getOutput()).hasSize(10); + + // check outputs + assertThat(output.getOutput(TnmOutput.DERIVED_VERSION.toString())).isEqualTo("1.9"); + assertThat(output.getOutput(TnmOutput.CLIN_STAGE_GROUP.toString())).isEqualTo("3"); + assertThat(output.getOutput(TnmOutput.PATH_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(TnmOutput.COMBINED_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(TnmOutput.COMBINED_T.toString())).isEqualTo("c0"); + assertThat(output.getOutput(TnmOutput.SOURCE_T.toString())).isEqualTo("1"); + assertThat(output.getOutput(TnmOutput.COMBINED_N.toString())).isEqualTo("c1"); + assertThat(output.getOutput(TnmOutput.SOURCE_N.toString())).isEqualTo("1"); + assertThat(output.getOutput(TnmOutput.COMBINED_M.toString())).isEqualTo("p1"); + assertThat(output.getOutput(TnmOutput.SOURCE_M.toString())).isEqualTo("2"); + } + + @Test + void testEodInputBuilder() { + EodStagingData data1 = new EodStagingData(); + data1.setInput(EodInput.PRIMARY_SITE, "C250"); + data1.setInput(EodInput.HISTOLOGY, "8154"); + data1.setInput(EodInput.DX_YEAR, "2018"); + data1.setInput(EodInput.AGE_AT_DX, "060"); + data1.setInput(EodInput.SEX, "1"); + data1.setInput(EodInput.TUMOR_SIZE_SUMMARY, "004"); + data1.setInput(EodInput.NODES_POS, "03"); + data1.setInput(EodInput.EOD_PRIMARY_TUMOR, "500"); + data1.setInput(EodInput.EOD_REGIONAL_NODES, "300"); + data1.setInput(EodInput.EOD_METS, "10"); + + EodStagingData data2 = new EodStagingInputBuilder() + .withInput(EodInput.PRIMARY_SITE, "C250") + .withInput(EodInput.HISTOLOGY, "8154") + .withInput(EodInput.DX_YEAR, "2018") + .withInput(EodInput.AGE_AT_DX, "060") + .withInput(EodInput.SEX, "1") + .withInput(EodInput.TUMOR_SIZE_SUMMARY, "004") + .withInput(EodInput.NODES_POS, "03") + .withInput(EodInput.EOD_PRIMARY_TUMOR, "500") + .withInput(EodInput.EOD_REGIONAL_NODES, "300") + .withInput(EodInput.EOD_METS, "10").build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); } @Test - public void testStagingWithErrors() throws IOException { + void testEodStaging() throws IOException { + EodStagingData data = new EodStagingInputBuilder() + .withInput(EodInput.PRIMARY_SITE, "C250") + .withInput(EodInput.HISTOLOGY, "8154") + .withInput(EodInput.DX_YEAR, "2018") + .withInput(EodInput.TUMOR_SIZE_SUMMARY, "004") + .withInput(EodInput.NODES_POS, "03") + .withInput(EodInput.EOD_PRIMARY_TUMOR, "500") + .withInput(EodInput.EOD_REGIONAL_NODES, "300") + .withInput(EodInput.EOD_METS, "10").build(); + + // perform the staging + StagingData output = _STAGING.stage("eod_public", "2.1", data.getInput()).execute().body(); + + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getSchemaId()).isEqualTo("pancreas"); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(12); + assertThat(output.getOutput()).hasSize(9); + + // check outputs + assertThat(output.getOutput(EodOutput.DERIVED_VERSION.toString())).isEqualTo("2.1"); + assertThat(output.getOutput(EodOutput.SS_2018_DERIVED.toString())).isEqualTo("7"); + assertThat(output.getOutput(EodOutput.NAACCR_SCHEMA_ID.toString())).isEqualTo("00280"); + assertThat(output.getOutput(EodOutput.EOD_2018_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(EodOutput.EOD_2018_T.toString())).isEqualTo("T1a"); + assertThat(output.getOutput(EodOutput.EOD_2018_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(EodOutput.EOD_2018_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(EodOutput.AJCC_ID.toString())).isEqualTo("28"); + } + + @Test + void testStagingWithErrors() throws IOException { StagingData data = new StagingData(); data.setInput("site", "C181"); data.setInput("hist", "8093"); @@ -208,8 +529,58 @@ public void testStagingWithErrors() throws IOException { // perform the staging StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); - assertEquals(StagingData.Result.STAGED, output.getResult()); - assertEquals(9, output.getErrors().size()); + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getErrors()).hasSize(9); + } + + @Test + void testStagingGlossary() throws IOException { + Set matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", null, true).execute().body(); + assertThat(matches).hasSize(26); + matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", EnumSet.of(Category.GENERAL), true).execute().body(); + assertThat(matches).hasSize(26); + + matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", null, true).execute().body(); + assertThat(matches).hasSize(23); + matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", EnumSet.of(Category.STAGING), true).execute().body(); + assertThat(matches).isEmpty(); + } + + @Test + void testStagingMetadata() throws IOException { + StagingSchema schema = _STAGING.schemaById("eod_public", "2.0", "brain").execute().body(); + assertThat(schema).isNotNull(); + + StagingSchemaInput mgmt = schema.getInputs().stream().filter(i -> i.getKey().equals("mgmt")).findFirst().orElse(null); + assertThat(mgmt).isNotNull(); + + assertThat(mgmt.getMetadata()).extracting("name").containsExactlyInAnyOrder("COC_REQUIRED", "SEER_REQUIRED", "SSDI"); + } + + @Test + void testBeans() { + MatcherAssert.assertThat(StagingAlgorithm.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters(), hasValidBeanEquals())); + MatcherAssert.assertThat(StagingVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSettersExcluding("production", "beta", "development"))); + MatcherAssert.assertThat(StagingSchema.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInfo.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingTable.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingTablePath.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingColumnDefinition.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingKeyMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingKeyValue.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingError.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRangeString.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRangeInteger.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DateRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DateRangeString.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index 116cc01..111d59d 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -6,64 +6,59 @@ import java.io.IOException; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; -import com.imsweb.seerapi.client.shared.Version; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static org.assertj.core.api.Assertions.assertThat; -public class SurgeryTest { +class SurgeryTest { private static SurgeryService _SURGERY; - @BeforeClass + @BeforeAll public static void setup() { _SURGERY = new SeerApi.Builder().connect().surgery(); } @Test - public void testSiteSpecificSurgeryVersions() throws IOException { - List versions = _SURGERY.versions().execute().body(); - - assertTrue(versions.size() > 0); - for (Version version : versions) { - assertTrue(version.getVersion().length() > 0); - assertTrue(version.getCount() > 0); - } - } - - @Test - public void testSiteSpecificSurgeryTables() throws IOException { + void testSiteSpecificSurgeryTables() throws IOException { List titles = _SURGERY.tables("2014").execute().body(); - assertTrue(titles.size() > 0); - assertTrue(titles.contains("Oral Cavity")); + assertThat(titles).isNotEmpty().containsAnyOf("Oral Cavity"); } @Test - public void testSiteSpecificSurgeryTable() throws IOException { + void testSiteSpecificSurgeryTable() throws IOException { SurgeryTable table = _SURGERY.table("2014", "Oral Cavity", null, null).execute().body(); - assertNotNull(table); - assertEquals("Oral Cavity", table.getTitle()); - assertNotNull(table.getSiteInclusions()); - assertNotNull(table.getHistExclusions()); - assertNull(table.getHistInclusions()); - assertNotNull(table.getPreNote()); - assertNull(table.getPostNote()); + assertThat(table).isNotNull(); + assertThat(table.getTitle()).isEqualTo("Oral Cavity"); + assertThat(table.getSiteInclusions()).isNotNull(); + assertThat(table.getHistExclusions()).isNotNull(); + assertThat(table.getHistInclusions()).isNull(); + assertThat(table.getPreNote()).isNotNull(); + assertThat(table.getPostNote()).isNull(); + SurgeryRow row = table.getRows().get(0); - assertEquals("00", row.getCode()); - assertNotNull(row.getDescription()); - assertEquals(Integer.valueOf(0), row.getLevel()); - assertFalse(row.getLineBreak()); + assertThat(row.getCode()).isEqualTo("00"); + assertThat(row.getDescription()).isNotNull(); + assertThat(row.getLevel()).isEqualTo(Integer.valueOf(0)); + assertThat(row.getLineBreak()).isFalse(); table = _SURGERY.table("2014", null, "C001", "8000").execute().body(); - assertEquals("Oral Cavity", table.getTitle()); + assertThat(table).isNotNull(); + assertThat(table.getTitle()).isEqualTo("Oral Cavity"); + } + + @Test + void testBeans() { + MatcherAssert.assertThat(SurgeryTable.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SurgeryRow.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java new file mode 100644 index 0000000..45a9f4e --- /dev/null +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2024 Information Management Services, Inc. + */ +package com.imsweb.seerapi.compare; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.disease.Disease; +import com.imsweb.seerapi.client.disease.DiseaseSearchResults; +import com.imsweb.seerapi.client.disease.DiseaseService; +import com.imsweb.seerapi.client.glossary.Glossary; +import com.imsweb.seerapi.client.glossary.GlossarySearchResults; +import com.imsweb.seerapi.client.glossary.GlossaryService; +import com.imsweb.seerapi.client.hcpcs.Hcpcs; +import com.imsweb.seerapi.client.hcpcs.HcpcsService; +import com.imsweb.seerapi.client.ndc.NdcProduct; +import com.imsweb.seerapi.client.ndc.NdcService; +import com.imsweb.seerapi.client.rx.Rx; +import com.imsweb.seerapi.client.rx.RxSearchResults; +import com.imsweb.seerapi.client.rx.RxService; +import com.imsweb.seerapi.client.staging.StagingAlgorithm; +import com.imsweb.seerapi.client.staging.StagingSchema; +import com.imsweb.seerapi.client.staging.StagingSchemaInfo; +import com.imsweb.seerapi.client.staging.StagingService; +import com.imsweb.seerapi.client.staging.StagingTable; +import com.imsweb.seerapi.client.staging.StagingVersion; + +import static org.assertj.core.api.Assertions.assertThat; + +@Disabled("Only for manual testing") +class ComparisonTest { + + private static final String PROD_URL = "https://api.seer.cancer.gov/rest/"; + private static final String LOCAL_URL = "http://localhost:8080/rest/"; + + private String getApiKey() { + return System.getenv("TESTING_API_KEY"); + } + + @Test + void testNdc() throws IOException { + NdcService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().ndc(); + NdcService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().ndc(); + + long page = 1; + long processed = 0; + + Map params = new HashMap<>(); + params.put("page", String.valueOf(page)); + params.put("per_page", "100"); + params.put("order", "ndc"); + List prodList = prodService.search(params).execute().body(); + List localList = localService.search(params).execute().body(); + + while (!Objects.requireNonNull(prodList).isEmpty() && !Objects.requireNonNull(localList).isEmpty()) { + processed += prodList.size(); + assertThat(localList) + .hasSameSizeAs(prodList) // Ensure both lists have the same size + .usingRecursiveComparison() + .isEqualTo(prodList); + + System.out.println("NDC page " + page + " (processed " + processed + " so far)"); + + page += 1; + params.put("page", String.valueOf(page)); + prodList = prodService.search(params).execute().body(); + localList = localService.search(params).execute().body(); + + // there are way too many entities; limit to 10,000 + if (processed >= 10_000) + break; + } + } + + @Test + void testHcpcs() throws IOException { + HcpcsService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().hcpcs(); + HcpcsService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().hcpcs(); + + long processed = 0; + long page = 1; + + Map params = new HashMap<>(); + params.put("page", String.valueOf(page)); + params.put("per_page", "100"); + params.put("order", "hcpcs_code"); + + List prodList = prodService.search(params).execute().body(); + List localList = localService.search(params).execute().body(); + + while (!Objects.requireNonNull(prodList).isEmpty()) { + processed += prodList.size(); + System.out.println("HCPCS page " + page + " (processed " + processed + " so far)"); + + assertThat(localList) + .hasSameSizeAs(prodList) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrderInFields("categories") + .isEqualTo(prodList); + + page += 1; + params.put("page", String.valueOf(page)); + prodList = prodService.search(params).execute().body(); + localList = localService.search(params).execute().body(); + } + } + + private Map getAlgorithmVersions() { + Map versions = new LinkedHashMap<>(); + + versions.put("pediatric", "1.2"); + versions.put("eod_public", "3.2"); + versions.put("tnm", "2.0"); + versions.put("cs", "02.05.50"); + + return versions; + } + + @Test + void testStagingAlgorithmsAndVersions() throws IOException { + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + List prodAlgorithms = prodService.algorithms().execute().body(); + List localAlgorithms = localService.algorithms().execute().body(); + + assertThat(localAlgorithms) + .hasSameSizeAs(prodAlgorithms) // Ensure both lists have the same size + .usingRecursiveComparison() + .isEqualTo(prodAlgorithms); + + for (StagingAlgorithm algorithm : Objects.requireNonNull(prodAlgorithms)) { + List prodVersions = prodService.versions(algorithm.getAlgorithm()).execute().body(); + List localVersions = localService.versions(algorithm.getAlgorithm()).execute().body(); + + assertThat(localVersions) + .hasSameSizeAs(prodVersions) + .usingRecursiveComparison() + .isEqualTo(prodVersions); + } + } + + @Test + void testStagingSchemas() throws IOException { + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + Map algorithmMap = getAlgorithmVersions(); + for (String algorithmId : algorithmMap.keySet()) { + String algorithmVersion = algorithmMap.get(algorithmId); + + System.out.println("Getting list of all schemas in " + algorithmId + ":" + algorithmVersion); + + List prodSchemas = prodService.schemas(algorithmId, algorithmVersion).execute().body(); + List localSchemas = localService.schemas(algorithmId, algorithmVersion).execute().body(); + + assertThat(localSchemas) + .hasSameSizeAs(prodSchemas) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(prodSchemas); + + for (StagingSchemaInfo prodSchema : Objects.requireNonNull(prodSchemas)) { + StagingSchema prod = prodService.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + StagingSchema local = localService.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + + System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] schema " + prodSchema.getId()); + + assertThat(local) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .withComparatorForType( + (date1, date2) -> { + // ignore milliseconds when comparing two Date objects + long time1 = date1.getTime() / 1000; + long time2 = date2.getTime() / 1000; + return Long.compare(time1, time2); + }, + Date.class + ) + .isEqualTo(prod); + } + } + } + + @Test + void testStagingTables() throws IOException { + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + Map algorithmMap = getAlgorithmVersions(); + for (String algorithmId : algorithmMap.keySet()) { + String algorithmVersion = algorithmMap.get(algorithmId); + + System.out.println("Getting list of all tables in " + algorithmId + ":" + algorithmVersion); + + List prodTables = prodService.tables(algorithmId, algorithmVersion).execute().body(); + List localTables = localService.tables(algorithmId, algorithmVersion).execute().body(); + + assertThat(localTables) + .hasSameSizeAs(prodTables) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(prodTables); + + for (StagingTable prodTable : Objects.requireNonNull(prodTables)) { + StagingTable prod = prodService.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + StagingTable local = localService.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + + System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] table " + prodTable.getId()); + + assertThat(local) + .usingRecursiveComparison() + .withComparatorForType( + (date1, date2) -> { + // ignore milliseconds when comparing two Date objects + long time1 = date1.getTime() / 1000; + long time2 = date2.getTime() / 1000; + return Long.compare(time1, time2); + }, + Date.class + ) + .isEqualTo(prod); + } + } + } + + @Test + void testGlossary() throws IOException { + GlossaryService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().glossary(); + GlossaryService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().glossary(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for glossary 'latest' version"); + + GlossarySearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Glossary glossary : prod.getResults()) + ids.add(glossary.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for glossary 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Glossary prodGlossary = prodService.getById("latest", id).execute().body(); + Glossary localGlossary = localService.getById("latest", id).execute().body(); + + assertThat(localGlossary) + .usingRecursiveComparison() + .isEqualTo(prodGlossary); + } + } + + @Test + void testRx() throws IOException { + RxService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().rx(); + RxService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().rx(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for rx 'latest' version"); + + RxSearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Rx rx : prod.getResults()) + ids.add(rx.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for rx 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Rx prodRx = prodService.getById("latest", id).execute().body(); + Rx localRx = localService.getById("latest", id).execute().body(); + + assertThat(localRx) + .usingRecursiveComparison() + .isEqualTo(prodRx); + } + } + + @Test + void testDisease() throws IOException { + DiseaseService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().disease(); + DiseaseService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().disease(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for disease 'latest' version"); + + DiseaseSearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Disease disease : prod.getResults()) + ids.add(disease.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for disease 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Disease prodDisease = prodService.getById("latest", id).execute().body(); + Disease localDisease = localService.getById("latest", id).execute().body(); + + assertThat(localDisease) + .usingRecursiveComparison() + .isEqualTo(prodDisease); + } + } +}