1383 lines
56 KiB
Go
1383 lines
56 KiB
Go
package database
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/fastenhealth/fasten-onprem/backend/pkg"
|
|
mock_config "github.com/fastenhealth/fasten-onprem/backend/pkg/config/mock"
|
|
"github.com/fastenhealth/fasten-onprem/backend/pkg/event_bus"
|
|
"github.com/fastenhealth/fasten-onprem/backend/pkg/models"
|
|
sourceModels "github.com/fastenhealth/fasten-sources/clients/models"
|
|
sourcePkg "github.com/fastenhealth/fasten-sources/pkg"
|
|
"github.com/fastenhealth/gofhir-models/fhir401"
|
|
fhirutils "github.com/fastenhealth/gofhir-models/fhir401/utils"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/google/uuid"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
"golang.org/x/net/context"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSourceCredentialInterface(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
repo := new(SqliteRepository)
|
|
|
|
//assert
|
|
require.Implements(t, (*sourceModels.DatabaseRepository)(nil), repo, "should implement the DatabaseRepository interface from fasten-sources")
|
|
require.Implements(t, (*DatabaseRepository)(nil), repo, "should implement the DatabaseRepository interface")
|
|
}
|
|
|
|
// Define the suite, and absorb the built-in basic suite
|
|
// functionality from testify - including a T() method which
|
|
// returns the current testing context
|
|
type RepositoryTestSuite struct {
|
|
suite.Suite
|
|
MockCtrl *gomock.Controller
|
|
TestDatabase *os.File
|
|
}
|
|
|
|
// BeforeTest has a function to be executed right before the test starts and receives the suite and test names as input
|
|
func (suite *RepositoryTestSuite) BeforeTest(suiteName, testName string) {
|
|
suite.MockCtrl = gomock.NewController(suite.T())
|
|
|
|
dbFile, err := ioutil.TempFile("", fmt.Sprintf("%s.*.db", testName))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
suite.TestDatabase = dbFile
|
|
|
|
}
|
|
|
|
// AfterTest has a function to be executed right after the test finishes and receives the suite and test names as input
|
|
func (suite *RepositoryTestSuite) AfterTest(suiteName, testName string) {
|
|
suite.MockCtrl.Finish()
|
|
os.Remove(suite.TestDatabase.Name())
|
|
}
|
|
|
|
// In order for 'go test' to run this suite, we need to create
|
|
// a normal test function and pass our suite to suite.Run
|
|
func TestRepositoryTestSuite(t *testing.T) {
|
|
suite.Run(t, new(RepositoryTestSuite))
|
|
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestNewRepository() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
|
|
//test
|
|
_, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestCreateUser() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
dbRepo.CreateUser(context.Background(), userModel)
|
|
|
|
//assert
|
|
require.NotEmpty(suite.T(), userModel.ID)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestCreateUser_WithExitingUser_ShouldFail() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel2 := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel2)
|
|
//assert
|
|
require.Error(suite.T(), err)
|
|
}
|
|
|
|
// TODO: ensure user's cannot specify the ID when creating a user.
|
|
func (suite *RepositoryTestSuite) TestCreateUser_WithUserProvidedId_ShouldBeReplaced() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userProvidedId := uuid.New()
|
|
userModel := &models.User{
|
|
ModelBase: models.ModelBase{
|
|
ID: userProvidedId,
|
|
},
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
dbRepo.CreateUser(context.Background(), userModel)
|
|
|
|
//assert
|
|
require.NotEmpty(suite.T(), userModel.ID)
|
|
require.NotEqual(suite.T(), userProvidedId.String(), userModel.ID.String())
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetUserByUsername() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userModelResult, err := dbRepo.GetUserByUsername(context.Background(), "test_username")
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), userModel.ID, userModelResult.ID)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetUserByUsername_WithInvalidUsername() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
_, err = dbRepo.GetUserByUsername(context.Background(), "userdoesntexist")
|
|
|
|
//assert
|
|
require.Error(suite.T(), err)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithContextBackgroundAuthUser() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userModelResult, err := dbRepo.GetCurrentUser(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username"))
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), userModelResult)
|
|
require.Equal(suite.T(), userModelResult.Username, "test_username")
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithGinContextBackgroundAuthUser() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
//ginContext := gin.Context{}
|
|
w := httptest.NewRecorder()
|
|
ginContext, _ := gin.CreateTestContext(w)
|
|
ginContext.Set(pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
userModelResult, err := dbRepo.GetCurrentUser(ginContext)
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), userModelResult)
|
|
require.Equal(suite.T(), userModelResult.Username, "test_username")
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithContextBackgroundAuthUserAndNoUserExists_ShouldThrowError() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
userModelResult, err := dbRepo.GetCurrentUser(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username"))
|
|
|
|
//assert
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), userModelResult)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestCreateGlossaryEntry() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
glossaryEntry := &models.Glossary{
|
|
Code: "49727002",
|
|
CodeSystem: "2.16.840.1.113883.6.96",
|
|
Publisher: "U.S. National Library of Medicine",
|
|
Title: "Cough",
|
|
Url: "https://medlineplus.gov/cough.html?utm_source=mplusconnect&utm_medium=service",
|
|
Description: `<p>Coughing is a reflex that keeps your throat and airways clear. Although it can be annoying, coughing helps your body heal or protect itself. Coughs can be either acute or chronic. Acute coughs begin suddenly and usually last no more than 2 to 3 weeks. Acute coughs are the kind you most often get with a <a href="https://medlineplus.gov/commoncold.html?utm_source=mplusconnect">cold</a>, <a href="https://medlineplus.gov/flu.html?utm_source=mplusconnect">flu</a>, or <a href="https://medlineplus.gov/acutebronchitis.html?utm_source=mplusconnect">acute bronchitis</a>. Chronic coughs last longer than 2 to 3 weeks. Causes of chronic cough include:</p><ul>
|
|
<li><a href="https://medlineplus.gov/chronicbronchitis.html?utm_source=mplusconnect">Chronic bronchitis</a></li>
|
|
<li><a href="https://medlineplus.gov/asthma.html?utm_source=mplusconnect">Asthma</a></li>
|
|
<li><a href="https://medlineplus.gov/allergy.html?utm_source=mplusconnect">Allergies</a></li>
|
|
<li><a href="https://medlineplus.gov/copd.html?utm_source=mplusconnect">COPD</a> (chronic obstructive pulmonary disease)</li>
|
|
<li><a href="https://medlineplus.gov/gerd.html?utm_source=mplusconnect">GERD</a> (gastroesophageal reflux disease) </li>
|
|
<li><a href="https://medlineplus.gov/smoking.html?utm_source=mplusconnect">Smoking</a></li>
|
|
<li><a href="https://medlineplus.gov/throatdisorders.html?utm_source=mplusconnect">Throat disorders</a>, such as <a href="https://medlineplus.gov/croup.html?utm_source=mplusconnect">croup</a> in young children</li>
|
|
<li>Some medicines </li>
|
|
</ul>
|
|
|
|
<p>Water can help ease your cough - whether you drink it or add it to the air with a steamy shower or vaporizer. If you have a cold or the flu, antihistamines may work better than non-prescription <a href="https://medlineplus.gov/coldandcoughmedicines.html?utm_source=mplusconnect">cough medicines</a>. Children under four should not have cough medicine. For children over four, use caution and read labels carefully.</p>`,
|
|
}
|
|
err = dbRepo.CreateGlossaryEntry(context.Background(), glossaryEntry)
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.NotEmpty(suite.T(), glossaryEntry.ID)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestUpsertRawResource() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: testPatientData,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
foundPatientResource, err := dbRepo.GetResourceByResourceTypeAndId(authContext, "Patient", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
require.NotNil(suite.T(), foundPatientResource)
|
|
require.Equal(suite.T(), foundPatientResource.SourceID, testSourceCredential.ID)
|
|
|
|
//ensure that the raw resource data is the same (we don't want to modify the data)
|
|
var expectedPationData map[string]interface{}
|
|
err = json.Unmarshal(testPatientData, &expectedPationData)
|
|
require.NoError(suite.T(), err)
|
|
|
|
var actualPatientData map[string]interface{}
|
|
err = json.Unmarshal(foundPatientResource.ResourceRaw, &actualPatientData)
|
|
require.Equal(suite.T(), expectedPationData, actualPatientData)
|
|
}
|
|
|
|
//TODO create UPSERT test, where the resource already exists and we need to update it
|
|
|
|
func (suite *RepositoryTestSuite) TestUpsertRawResource_WithRelatedResourceAndDuplicateReference() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
patientData, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: patientData,
|
|
ReferencedResources: []string{"Observation/1", "Observation/2", "Observation/3", "Observation/3"}, //duplicate resource reference should not cause an issue, it should be silently ignored
|
|
},
|
|
)
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
relatedResource, err := dbRepo.FindResourceAssociationsByTypeAndId(authContext, &testSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 3, len(relatedResource))
|
|
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestListResources() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
otherUserModel := &models.User{
|
|
Username: "test_other_username",
|
|
Password: "testpassword",
|
|
Email: "testother@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), otherUserModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
testSource1Credential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
testSource2Credential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
patientDataAbraham100, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
testResource1Created, err := dbRepo.UpsertRawResource(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
&testSource1Credential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: patientDataAbraham100,
|
|
ReferencedResources: []string{"Observation/1", "Observation/2", "Observation/3", "Observation/3"}, //duplicate resource reference should not cause an issue, it should be silently ignored
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), testResource1Created)
|
|
|
|
patientDataLillia547, err := os.ReadFile("./testdata/Lillia547_Schneider99_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
testResource2Created, err := dbRepo.UpsertRawResource(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
&testSource2Credential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "d3fbfb3a-7b8d-45c0-13b4-9666e4d36a3e",
|
|
ResourceRaw: patientDataLillia547,
|
|
ReferencedResources: []string{"Observation/10", "Observation/20", "Observation/30"},
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), testResource2Created)
|
|
|
|
//test
|
|
foundPatientResources, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{
|
|
SourceResourceType: "Patient",
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
|
|
findAllResources, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{})
|
|
require.NoError(suite.T(), err)
|
|
|
|
findSourceResources, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{SourceID: testSource1Credential.ID.String()})
|
|
require.NoError(suite.T(), err)
|
|
|
|
//find specific resource
|
|
findSpecificResource, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{SourceResourceID: "d3fbfb3a-7b8d-45c0-13b4-9666e4d36a3e", SourceResourceType: "Patient"})
|
|
require.NoError(suite.T(), err)
|
|
|
|
findInvalidResource, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{SourceResourceID: "11111111-7b8d-45c0-13b4-9666e4d36a3e", SourceResourceType: "Patient"})
|
|
require.NoError(suite.T(), err)
|
|
|
|
findResourceWithOtherUserId, err := dbRepo.ListResources(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_other_username"), models.ListResourceQueryOptions{SourceResourceID: "d3fbfb3a-7b8d-45c0-13b4-9666e4d36a3e", SourceResourceType: "Patient"})
|
|
require.NoError(suite.T(), err)
|
|
|
|
_, err = dbRepo.ListResources(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "doesnt_exist"), models.ListResourceQueryOptions{SourceResourceID: "d3fbfb3a-7b8d-45c0-13b4-9666e4d36a3e", SourceResourceType: "Patient"})
|
|
require.Error(suite.T(), err)
|
|
|
|
//assert
|
|
require.Equal(suite.T(), len(foundPatientResources), 2)
|
|
require.Equal(suite.T(), len(findAllResources), 2)
|
|
require.Equal(suite.T(), len(findSourceResources), 1)
|
|
require.Equal(suite.T(), len(findSpecificResource), 1)
|
|
require.Equal(suite.T(), len(findInvalidResource), 0)
|
|
require.Equal(suite.T(), len(findResourceWithOtherUserId), 0)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetResourceByResourceTypeAndId() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: testPatientData,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
|
|
//test & assert
|
|
findPatientResource, err := dbRepo.GetResourceByResourceTypeAndId(authContext, "Patient", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), findPatientResource)
|
|
|
|
//raise an error if the resource is not found (invalid resource type or id missing)
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, "Patient", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), err)
|
|
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, "Observation", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), err)
|
|
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, "InvalidResource", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), err)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetResourceBySourceId() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: testPatientData,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
|
|
//test & assert
|
|
findPatientResource, err := dbRepo.GetResourceBySourceId(authContext, testSourceCredential.ID.String(), "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), findPatientResource)
|
|
|
|
//raise an error if the resource is not found (invalid resource id for source)
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, testSourceCredential.ID.String(), "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), err)
|
|
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, uuid.NewString(), "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), err)
|
|
|
|
_, err = dbRepo.GetResourceByResourceTypeAndId(authContext, testSourceCredential.ID.String(), "")
|
|
require.Error(suite.T(), err)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetPatientForSources() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_Patient.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "b426b062-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: testPatientData,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
|
|
was2Created, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: "Patient",
|
|
SourceResourceID: "11111111-8273-4b93-a907-de3176c0567d",
|
|
ResourceRaw: testPatientData,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), was2Created)
|
|
//test & assert
|
|
findPatients, err := dbRepo.GetPatientForSources(authContext)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), findPatients)
|
|
require.Len(suite.T(), findPatients, 2) //TODO: this may need to change to 1 if we group by source_id
|
|
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestAddResourceAssociation() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
|
|
//test
|
|
err = dbRepo.AddResourceAssociation(authContext,
|
|
&testSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d",
|
|
&testSourceCredential, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
|
|
//assert
|
|
related, err := dbRepo.FindResourceAssociationsByTypeAndId(authContext, &testSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 1, len(related))
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestAddResourceAssociation_WithMismatchingSourceIds() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
//test 1 - user id does not match the user id on resources (but they match eachother)
|
|
differentUserIdSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: uuid.New(),
|
|
}
|
|
errForUserMismatch := dbRepo.AddResourceAssociation(authContext,
|
|
&differentUserIdSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d",
|
|
&differentUserIdSourceCredential, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), errForUserMismatch)
|
|
|
|
//test 2 - user id for resources do not match eachother
|
|
sourceCredential1 := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: uuid.New(),
|
|
}
|
|
sourceCredential2 := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: uuid.New(),
|
|
}
|
|
require.NotEqual(suite.T(), sourceCredential1.UserID, sourceCredential2.UserID)
|
|
errForResourceMismatch := dbRepo.AddResourceAssociation(authContext,
|
|
&sourceCredential1, "Patient", "b426b062-8273-4b93-a907-de3176c0567d",
|
|
&sourceCredential2, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.Error(suite.T(), errForResourceMismatch)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestRemoveResourceAssociation() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
|
|
err = dbRepo.AddResourceAssociation(authContext,
|
|
&testSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d",
|
|
&testSourceCredential, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
errWhenNotExists := dbRepo.RemoveResourceAssociation(authContext,
|
|
&testSourceCredential, "Patient", "999999999-8273-4b93-a907-de3176c0567d",
|
|
&testSourceCredential, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.Errorf(suite.T(), errWhenNotExists, "association should not exist, so deletion should fail")
|
|
|
|
err = dbRepo.RemoveResourceAssociation(authContext,
|
|
&testSourceCredential, "Patient", "b426b062-8273-4b93-a907-de3176c0567d",
|
|
&testSourceCredential, "Observation", "11111111-8273-4b93-a907-de3176c0567d")
|
|
require.NoError(suite.T(), err)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetSourceSummary() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
err = dbRepo.CreateSource(authContext, &testSourceCredential)
|
|
require.NoError(suite.T(), err)
|
|
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_262b819a-5193-404a-9787-b7f599358035.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
var testPatientBundle fhir401.Bundle
|
|
err = json.Unmarshal(testPatientData, &testPatientBundle)
|
|
require.NoError(suite.T(), err)
|
|
|
|
for _, resourceEntry := range testPatientBundle.Entry {
|
|
|
|
fhirResource, _ := fhirutils.MapToResource(resourceEntry.Resource, false)
|
|
resourceType, resourceId := fhirResource.(sourceModels.ResourceInterface).ResourceRef()
|
|
if resourceId == nil {
|
|
suite.T().Logf("skipping resource with no ID: %s", resourceType)
|
|
continue //skip resources missing an ID
|
|
}
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: resourceType,
|
|
SourceResourceID: *resourceId,
|
|
ResourceRaw: resourceEntry.Resource,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
}
|
|
|
|
//test
|
|
sourceSummary, err := dbRepo.GetSourceSummary(authContext, testSourceCredential.ID.String())
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), sourceSummary)
|
|
//validated using https://www.maxmddirect.com/direct/FHIR/ResponseViewer
|
|
require.Equal(suite.T(), []map[string]interface{}{
|
|
{"count": int64(1), "resource_type": "CarePlan", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(1), "resource_type": "CareTeam", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(22), "resource_type": "Claim", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(8), "resource_type": "Condition", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(2), "resource_type": "DiagnosticReport", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(18), "resource_type": "Encounter", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(18), "resource_type": "ExplanationOfBenefit", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(16), "resource_type": "Immunization", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(4), "resource_type": "MedicationRequest", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(93), "resource_type": "Observation", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(3), "resource_type": "Organization", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(1), "resource_type": "Patient", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(3), "resource_type": "Practitioner", "source_id": testSourceCredential.ID.String()},
|
|
{"count": int64(8), "resource_type": "Procedure", "source_id": testSourceCredential.ID.String()},
|
|
}, sourceSummary.ResourceTypeCounts)
|
|
require.Equal(suite.T(), "b426b062-8273-4b93-a907-de3176c0567d", sourceSummary.Patient.SourceResourceID)
|
|
require.Equal(suite.T(), "Patient", sourceSummary.Patient.SourceResourceType)
|
|
require.NotEmpty(suite.T(), sourceSummary.Patient.ResourceRaw)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestGetSummary() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential1 := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
Patient: uuid.New().String(),
|
|
}
|
|
err = dbRepo.CreateSource(authContext, &testSourceCredential1)
|
|
require.NoError(suite.T(), err)
|
|
|
|
testSourceCredential2 := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
Patient: uuid.New().String(),
|
|
}
|
|
err = dbRepo.CreateSource(authContext, &testSourceCredential2)
|
|
require.NoError(suite.T(), err)
|
|
|
|
testPatientData, err := os.ReadFile("./testdata/Abraham100_Heller342_262b819a-5193-404a-9787-b7f599358035.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
var testPatientBundle fhir401.Bundle
|
|
err = json.Unmarshal(testPatientData, &testPatientBundle)
|
|
require.NoError(suite.T(), err)
|
|
|
|
for _, resourceEntry := range testPatientBundle.Entry {
|
|
|
|
fhirResource, _ := fhirutils.MapToResource(resourceEntry.Resource, false)
|
|
resourceType, resourceId := fhirResource.(sourceModels.ResourceInterface).ResourceRef()
|
|
if resourceId == nil {
|
|
suite.T().Logf("skipping resource with no ID: %s", resourceType)
|
|
continue //skip resources missing an ID
|
|
}
|
|
wasCreated, err := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential1,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: resourceType,
|
|
SourceResourceID: *resourceId,
|
|
ResourceRaw: resourceEntry.Resource,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
require.True(suite.T(), wasCreated)
|
|
|
|
wasCreated2, err2 := dbRepo.UpsertRawResource(
|
|
authContext,
|
|
&testSourceCredential2,
|
|
sourceModels.RawResourceFhir{
|
|
SourceResourceType: resourceType,
|
|
SourceResourceID: *resourceId + "2",
|
|
ResourceRaw: resourceEntry.Resource,
|
|
},
|
|
)
|
|
require.NoError(suite.T(), err2)
|
|
require.True(suite.T(), wasCreated2)
|
|
}
|
|
|
|
//test
|
|
sourceSummary, err := dbRepo.GetSummary(authContext)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), sourceSummary)
|
|
//validated using https://www.maxmddirect.com/direct/FHIR/ResponseViewer
|
|
require.Equal(suite.T(), []map[string]interface{}{
|
|
{"count": int64(2), "resource_type": "CarePlan"},
|
|
{"count": int64(2), "resource_type": "CareTeam"},
|
|
{"count": int64(44), "resource_type": "Claim"},
|
|
{"count": int64(16), "resource_type": "Condition"},
|
|
{"count": int64(4), "resource_type": "DiagnosticReport"},
|
|
{"count": int64(36), "resource_type": "Encounter"},
|
|
{"count": int64(36), "resource_type": "ExplanationOfBenefit"},
|
|
{"count": int64(32), "resource_type": "Immunization"},
|
|
{"count": int64(8), "resource_type": "MedicationRequest"},
|
|
{"count": int64(93 * 2), "resource_type": "Observation"},
|
|
{"count": int64(6), "resource_type": "Organization"},
|
|
{"count": int64(2), "resource_type": "Patient"},
|
|
{"count": int64(6), "resource_type": "Practitioner"},
|
|
{"count": int64(16), "resource_type": "Procedure"},
|
|
}, sourceSummary.ResourceTypeCounts)
|
|
|
|
require.Equal(suite.T(), 2, len(sourceSummary.Sources))
|
|
require.Equal(suite.T(), 2, len(sourceSummary.Patients))
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestAddResourceComposition() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
Patient: uuid.New().String(),
|
|
}
|
|
err = dbRepo.CreateSource(authContext, &testSourceCredential)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
testCompositionData, err := os.ReadFile("./testdata/Composition_Create.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
type CompositionPayload struct {
|
|
Title string `json:"title"`
|
|
Resources []*models.ResourceBase `json:"resources"`
|
|
}
|
|
var compositionPayload CompositionPayload
|
|
err = json.Unmarshal(testCompositionData, &compositionPayload)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//update resources with testSource Credential
|
|
for i, _ := range compositionPayload.Resources {
|
|
compositionPayload.Resources[i].SourceID = testSourceCredential.ID
|
|
}
|
|
err = dbRepo.AddResourceComposition(authContext, compositionPayload.Title, compositionPayload.Resources)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//assert
|
|
//check that composition was created
|
|
compositions, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{
|
|
SourceID: "00000000-0000-0000-0000-000000000000",
|
|
SourceResourceType: "Composition",
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 1, len(compositions))
|
|
|
|
//assert that the associations were created
|
|
associations, err := dbRepo.FindResourceAssociationsByTypeAndId(authContext,
|
|
&models.SourceCredential{UserID: userModel.ID, ModelBase: models.ModelBase{ID: uuid.MustParse("00000000-0000-0000-0000-000000000000")}}, //Compositions have a unique/placeholder credential ID
|
|
"Composition", compositions[0].SourceResourceID)
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 2, len(associations))
|
|
require.Equal(suite.T(), []models.RelatedResource{
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Condition",
|
|
RelatedResourceSourceResourceID: "bec92fdc-8765-409b-9850-52786d31aa9b",
|
|
},
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Condition",
|
|
RelatedResourceSourceResourceID: "cf39b665-4177-41e3-af34-149421cb895f",
|
|
},
|
|
}, associations)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestAddResourceComposition_WithExistingComposition() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.MustParse("00000000-0000-0000-0000-000000000000"),
|
|
},
|
|
UserID: userModel.ID,
|
|
Patient: uuid.New().String(),
|
|
}
|
|
err = dbRepo.CreateSource(authContext, &testSourceCredential)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//create existing composition
|
|
emptyRawJson, err := json.Marshal(map[string]interface{}{})
|
|
require.NoError(suite.T(), err)
|
|
err = dbRepo.AddResourceComposition(authContext, "existing composition", []*models.ResourceBase{
|
|
{
|
|
OriginBase: models.OriginBase{
|
|
SourceID: testSourceCredential.ID,
|
|
SourceResourceType: "Observation",
|
|
SourceResourceID: "1",
|
|
},
|
|
ResourceRaw: emptyRawJson,
|
|
},
|
|
{
|
|
OriginBase: models.OriginBase{
|
|
SourceID: testSourceCredential.ID,
|
|
SourceResourceType: "Observation",
|
|
SourceResourceID: "2",
|
|
},
|
|
ResourceRaw: emptyRawJson,
|
|
},
|
|
{
|
|
OriginBase: models.OriginBase{
|
|
SourceID: testSourceCredential.ID,
|
|
SourceResourceType: "Observation",
|
|
SourceResourceID: "3",
|
|
},
|
|
ResourceRaw: emptyRawJson,
|
|
},
|
|
})
|
|
|
|
require.NoError(suite.T(), err)
|
|
|
|
//find existing composition
|
|
existingCompositions, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{
|
|
SourceID: "00000000-0000-0000-0000-000000000000",
|
|
SourceResourceType: "Composition",
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 1, len(existingCompositions), "Only 1 composition should exist at this point")
|
|
|
|
//test
|
|
testCompositionData, err := os.ReadFile("./testdata/Composition_Create.json")
|
|
require.NoError(suite.T(), err)
|
|
|
|
type CompositionPayload struct {
|
|
Title string `json:"title"`
|
|
Resources []*models.ResourceBase `json:"resources"`
|
|
}
|
|
var compositionPayload CompositionPayload
|
|
err = json.Unmarshal(testCompositionData, &compositionPayload)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//update resources with testSource Credential
|
|
for i, _ := range compositionPayload.Resources {
|
|
compositionPayload.Resources[i].SourceID = testSourceCredential.ID
|
|
}
|
|
//add the existing composition as a resource to this composition
|
|
compositionPayload.Resources = append(compositionPayload.Resources, &existingCompositions[0])
|
|
|
|
//test
|
|
err = dbRepo.AddResourceComposition(authContext, compositionPayload.Title, compositionPayload.Resources)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//assert
|
|
//check that composition was created
|
|
compositions, err := dbRepo.ListResources(authContext, models.ListResourceQueryOptions{
|
|
SourceID: "00000000-0000-0000-0000-000000000000",
|
|
SourceResourceType: "Composition",
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 1, len(compositions), "Only 1 composition should exist, the previous one should be deleted, and its related resources merged into this one.")
|
|
|
|
//assert that the associations were created
|
|
associations, err := dbRepo.FindResourceAssociationsByTypeAndId(authContext,
|
|
&models.SourceCredential{UserID: userModel.ID, ModelBase: models.ModelBase{ID: uuid.MustParse("00000000-0000-0000-0000-000000000000")}}, //Compositions have a unique/placeholder credential ID
|
|
"Composition", compositions[0].SourceResourceID)
|
|
require.NoError(suite.T(), err)
|
|
require.Equal(suite.T(), 5, len(associations))
|
|
require.Equal(suite.T(), []models.RelatedResource{
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Condition",
|
|
RelatedResourceSourceResourceID: "bec92fdc-8765-409b-9850-52786d31aa9b",
|
|
},
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Condition",
|
|
RelatedResourceSourceResourceID: "cf39b665-4177-41e3-af34-149421cb895f",
|
|
},
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Observation",
|
|
RelatedResourceSourceResourceID: "1",
|
|
},
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Observation",
|
|
RelatedResourceSourceResourceID: "2",
|
|
},
|
|
{
|
|
ResourceBaseUserID: testSourceCredential.UserID,
|
|
ResourceBaseSourceID: compositions[0].SourceID,
|
|
ResourceBaseSourceResourceType: "Composition",
|
|
ResourceBaseSourceResourceID: compositions[0].SourceResourceID,
|
|
RelatedResourceUserID: testSourceCredential.UserID,
|
|
RelatedResourceSourceID: testSourceCredential.ID,
|
|
RelatedResourceSourceResourceType: "Observation",
|
|
RelatedResourceSourceResourceID: "3",
|
|
},
|
|
}, associations)
|
|
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestCreateBackgroundJob_Sync() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
//test
|
|
sourceCredential := models.SourceCredential{ModelBase: models.ModelBase{ID: uuid.New()}, SourceType: sourcePkg.SourceType("bluebutton")}
|
|
backgroundJob := models.NewSyncBackgroundJob(sourceCredential)
|
|
err = dbRepo.CreateBackgroundJob(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
backgroundJob,
|
|
)
|
|
|
|
//assert
|
|
require.NoError(suite.T(), err)
|
|
require.NotEqual(suite.T(), uuid.Nil, backgroundJob.ID)
|
|
require.Equal(suite.T(), pkg.BackgroundJobTypeSync, backgroundJob.JobType)
|
|
require.Equal(suite.T(), pkg.BackgroundJobStatusLocked, backgroundJob.JobStatus)
|
|
require.NotNil(suite.T(), backgroundJob.LockedTime)
|
|
require.Nil(suite.T(), backgroundJob.DoneTime)
|
|
require.Equal(suite.T(), userModel.ID, backgroundJob.UserID)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestListBackgroundJobs() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
otherUserModel := &models.User{
|
|
Username: "test_other_username",
|
|
Password: "testpassword",
|
|
Email: "testother@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), otherUserModel)
|
|
require.NoError(suite.T(), err)
|
|
|
|
testSourceCredential := models.SourceCredential{
|
|
ModelBase: models.ModelBase{
|
|
ID: uuid.New(),
|
|
},
|
|
UserID: userModel.ID,
|
|
}
|
|
|
|
backgroundJob := models.NewSyncBackgroundJob(testSourceCredential)
|
|
err = dbRepo.CreateBackgroundJob(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
backgroundJob,
|
|
)
|
|
|
|
backgroundJob2 := models.NewSyncBackgroundJob(testSourceCredential)
|
|
backgroundJob2.JobType = pkg.BackgroundJobTypeScheduledSync
|
|
err = dbRepo.CreateBackgroundJob(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
backgroundJob2,
|
|
)
|
|
|
|
backgroundJob3 := models.NewSyncBackgroundJob(testSourceCredential)
|
|
backgroundJob3.JobStatus = pkg.BackgroundJobStatusFailed
|
|
err = dbRepo.CreateBackgroundJob(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
backgroundJob3,
|
|
)
|
|
|
|
require.NoError(suite.T(), err)
|
|
|
|
//test
|
|
foundAllBackgroundJobs, err := dbRepo.ListBackgroundJobs(authContext, models.BackgroundJobQueryOptions{})
|
|
require.NoError(suite.T(), err)
|
|
|
|
syncJobType := pkg.BackgroundJobTypeSync
|
|
foundBackgroundJobsByType, err := dbRepo.ListBackgroundJobs(authContext, models.BackgroundJobQueryOptions{
|
|
JobType: &syncJobType,
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
|
|
syncFailedStatus := pkg.BackgroundJobStatusFailed
|
|
foundBackgroundJobsByStatus, err := dbRepo.ListBackgroundJobs(authContext, models.BackgroundJobQueryOptions{
|
|
Status: &syncFailedStatus,
|
|
})
|
|
require.NoError(suite.T(), err)
|
|
|
|
//assert
|
|
require.Equal(suite.T(), len(foundAllBackgroundJobs), 3)
|
|
require.Equal(suite.T(), len(foundBackgroundJobsByType), 2)
|
|
require.Equal(suite.T(), len(foundBackgroundJobsByStatus), 1)
|
|
}
|
|
|
|
func (suite *RepositoryTestSuite) TestUpdateBackgroundJob() {
|
|
//setup
|
|
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
|
|
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
|
|
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
|
|
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
|
|
require.NoError(suite.T(), err)
|
|
|
|
userModel := &models.User{
|
|
Username: "test_username",
|
|
Password: "testpassword",
|
|
Email: "test@test.com",
|
|
}
|
|
err = dbRepo.CreateUser(context.Background(), userModel)
|
|
require.NoError(suite.T(), err)
|
|
authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
|
|
|
|
sourceCredential := models.SourceCredential{ModelBase: models.ModelBase{ID: uuid.New()}, SourceType: sourcePkg.SourceType("bluebutton")}
|
|
backgroundJob := models.NewSyncBackgroundJob(sourceCredential)
|
|
err = dbRepo.CreateBackgroundJob(
|
|
context.WithValue(authContext, pkg.ContextKeyTypeAuthUsername, "test_username"),
|
|
backgroundJob,
|
|
)
|
|
|
|
//test
|
|
now := time.Now()
|
|
backgroundJob.JobStatus = pkg.BackgroundJobStatusFailed
|
|
backgroundJob.DoneTime = &now
|
|
|
|
err = dbRepo.UpdateBackgroundJob(
|
|
authContext,
|
|
backgroundJob,
|
|
)
|
|
require.NoError(suite.T(), err)
|
|
|
|
//list all records and ensure that the updated record is the same
|
|
foundAllBackgroundJobs, err := dbRepo.ListBackgroundJobs(authContext, models.BackgroundJobQueryOptions{})
|
|
require.NoError(suite.T(), err)
|
|
|
|
//assert
|
|
require.Equal(suite.T(), 1, len(foundAllBackgroundJobs))
|
|
require.Equal(suite.T(), backgroundJob.ID, foundAllBackgroundJobs[0].ID)
|
|
require.Equal(suite.T(), pkg.BackgroundJobStatusFailed, foundAllBackgroundJobs[0].JobStatus)
|
|
require.NotNil(suite.T(), foundAllBackgroundJobs[0].DoneTime)
|
|
}
|