Compare commits

..

1 Commits

Author SHA1 Message Date
mohamedkaif356
dcc7a921a0 Offline Incubation time 2023-11-14 22:58:34 +05:30
21 changed files with 341 additions and 207 deletions

View File

@@ -71,16 +71,15 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta11'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta11")
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta10'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta10")
// Testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
testImplementation 'org.mockito:mockito-core:3.12.0'
testImplementation "androidx.arch.core:core-testing:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
implementation 'com.opencsv:opencsv:4.6'

View File

@@ -8,6 +8,8 @@ data class HemoCubeTestData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var incubationTime: String = "",
var bloodGroup: String = "",
var birthYear: String = "",
var userImageURL: String = "",
var location: UserData.Location? = null,

View File

@@ -9,6 +9,7 @@ data class UserData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var bloodGroup: String = "",
var incubationTime: String = "",
var birthYear: String = "",
var userImageURL: String = "",

View File

@@ -1,29 +0,0 @@
package com.example.hpostesting.di
import android.content.Context
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@Provides
fun provideTestRightViewModel(
saveRawData: SaveRawData,
saveRawDataTest: SaveRawDataTest,
databaseRepository: DatabaseRepository,
userDao: UserDao,
context: Context
): TestRightViewModel {
return TestRightViewModel(saveRawData, saveRawDataTest, databaseRepository, userDao, context)
}
}

View File

@@ -138,8 +138,4 @@ class DatabaseRepository : Repository {
// Find the DeviceData object with the specified deviceId
return allDeviceDataList.find { it.deviceId == deviceId }
}
override fun <UserData> addTestToDatabase(testDetails: UserData): Any {
TODO("Not yet implemented")
}
}

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.data.repository
interface Repository {
abstract fun <UserData> addTestToDatabase(testDetails: UserData): Any
// suspend fun addToDatabase(data: PatientDetails)
}

View File

@@ -0,0 +1,121 @@
package com.example.hpostesting.presentation.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
class OfflineUserListAdapter(private val view: View, private val batLevel: Int) :
RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() {
inner class OfflineUserListViewHolder(val binding: OfflineUserListViewBinding) :
RecyclerView.ViewHolder(binding.root)
private val differCallback = object : DiffUtil.ItemCallback<HemoCubeTestData>() {
override fun areItemsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData
): Boolean {
return oldItem._id == newItem._id
}
override fun areContentsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData
): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OfflineUserListViewHolder {
return OfflineUserListViewHolder(
OfflineUserListViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun getItemCount(): Int {
return differ.currentList.size
}
override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) {
val userList = differ.currentList[position]
holder.binding.apply {
userID.text = "User ID: ${userList._id}"
bloodGroup.text = "Blood group: ${userList.bloodGroup}"
time.text = "Time: ${userList.incubationTime}"
userCard.setOnClickListener {
if (batLevel < 40) {
Toast.makeText(
view.context,
"Battery level is low than 40%, please charge the device to continue testing",
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (userList.testStatus != null) {
if (userList.testStatus!!) {
Toast.makeText(
view.context,
"Test has been already conducted for this user",
Toast.LENGTH_SHORT
).show()
} else {
if (userList.incubationTime != "") {
if (isBetween15And30Minutes(userList.incubationTime) < 15) {
Toast.makeText(
view.context,
"Incubation has not completed 15 minutes",
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(userList.incubationTime) > 30) {
Toast.makeText(
view.context,
"Incubation crossed 30 minutes, need to repeat the incubation",
Toast.LENGTH_SHORT
).show()
} else {
DataHolder.selectedTest = UserData(
_id = userList._id,
bloodGroup = userList.bloodGroup,
incubationTime = userList.incubationTime
)
view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity)
}
} else {
Toast.makeText(
view.context,
"Incubation not started for this user",
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
}
private fun isBetween15And30Minutes(createdAt: String): Long {
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val createdAtDate: Date = formatter.parse(createdAt)!!
val currentTime = Calendar.getInstance().time
val diffMillis = currentTime.time - createdAtDate.time
return diffMillis / (60 * 1000)
}
}

View File

@@ -20,6 +20,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
@@ -33,6 +34,7 @@ import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
@@ -40,10 +42,12 @@ import java.util.Locale
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private val viewModel: TestRightViewModel<Any?> by activityViewModels()
private val viewModel: TestRightViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter
private var batLevel: Int = 0 // Initialize with a default value, or obtain the actual battery level
private var batLevel: Int =
0 // Initialize with a default value, or obtain the actual battery level
private lateinit var adapter: OfflineUserListAdapter
private lateinit var sharedPreference: SharedPreferences
@@ -73,6 +77,19 @@ class HomeFragment : Fragment() {
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteHemoCubeIncompleteRegistrations(userData)
if (userData.isNotEmpty()) {
val userList = mutableListOf<HemoCubeTestData>()
userData.forEach {
if (it.testStatus == false) {
userList.add(it)
}
}
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel)
adapter.differ.submitList(userList)
binding.rvOrderOffline.adapter = adapter
}
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected ->
if (isConnected) {
@@ -120,10 +137,18 @@ class HomeFragment : Fragment() {
private fun setUserId() {
binding.btnSubmit.setOnClickListener {
val userId = binding.userId.text.toString()
if (userId.length >= 18) {
val userData = UserData(_id = userId)
DataHolder.selectedTest = userData
findNavController().navigate(R.id.action_nav_home_to_mainActivity)
val bloodGroup = binding.etBloodGroup.text
if (userId.length >= 18 && !bloodGroup.equals("Select Blood Group") || !bloodGroup.isNullOrBlank()) {
hemoCubeViewModel.addUser(
HemoCubeTestData(
_id = userId, bloodGroup = bloodGroup.toString(), incubationTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time).toString()
)
)
// val userData = UserData(_id = userId)
// DataHolder.selectedTest = userData
// findNavController().navigate(R.id.action_nav_home_to_mainActivity)
} else {
val errorMessage = getString(R.string.user_id_error_message)
Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show()
@@ -155,10 +180,12 @@ class HomeFragment : Fragment() {
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
rvAdapter = view?.let {
UserListAdapter(requireContext(), hemoCubeViewModel, recyclerViewOptions,
it, batLevel, requireActivity())
}!!
rvAdapter = view?.let {
UserListAdapter(
requireContext(), hemoCubeViewModel, recyclerViewOptions,
it, batLevel, requireActivity()
)
}!!
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
@@ -206,8 +233,9 @@ class HomeFragment : Fragment() {
val partition = dateFormat.format(currentDate)
val searchTerm = partition + search
val searchField = field + "Search"
val query = Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm)
.endAt(searchTerm + "\uf8ff")
val query =
Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm)
.endAt(searchTerm + "\uf8ff")
query.get().addOnSuccessListener {
userSearchTrace.stop()
}
@@ -218,7 +246,14 @@ class HomeFragment : Fragment() {
batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
rvAdapter = view?.let {
UserListAdapter(requireContext(), hemoCubeViewModel, recyclerViewOptions, it, batLevel, requireActivity())
UserListAdapter(
requireContext(),
hemoCubeViewModel,
recyclerViewOptions,
it,
batLevel,
requireActivity()
)
}!!
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
@@ -272,7 +307,8 @@ class HomeFragment : Fragment() {
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility = if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE
val uploadDataVisibility =
if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE
binding.uploadData.visibility = uploadDataVisibility
}
}
@@ -331,7 +367,7 @@ class HomeFragment : Fragment() {
private fun deleteHemoCubeIncompleteRegistrations(userDataList: List<HemoCubeTestData>) {
userDataList.forEach { userData ->
if (userData.testTime?.isEmpty() == true) {
if (userData._id.isEmpty()) {
hemoCubeViewModel.deleteById(userData._id)
}
}

View File

@@ -309,7 +309,7 @@ class HemoCubeFragment : Fragment() {
}
}
fun handleValidResult(validString: String, fullReadOutput: String) {
private fun handleValidResult(validString: String, fullReadOutput: String) {
try {
val result = validString.split(" ")
val deviceLog = resultData

View File

@@ -15,6 +15,7 @@ import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -183,6 +184,10 @@ class HemoCubeViewModel @Inject constructor(
hemoCubeDao.updateFieldById(id = userId, true)
}
fun addUser(userData: HemoCubeTestData) = viewModelScope.launch {
hemoCubeDao.insertAll(userData)
}
fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId)
}

View File

@@ -32,7 +32,7 @@ import `in`.sminnovations.hpostesting.databinding.ActivityTestRightBinding
class TestRightActivity : AppCompatActivity() {
private lateinit var binding: ActivityTestRightBinding
private val viewModel by viewModels<TestRightViewModel<Any?>>()
private val viewModel by viewModels<TestRightViewModel>()
private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver

View File

@@ -25,7 +25,7 @@ import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceB
@AndroidEntryPoint
class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding
private val viewModel: TestRightViewModel<Any?> by activityViewModels()
private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightExpReference"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?

View File

@@ -27,7 +27,7 @@ import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpSampleBind
class TestRightExpSample : Fragment() {
private lateinit var binding: FragmentTestRightExpSampleBinding
private val viewModel: TestRightViewModel<Any?> by activityViewModels()
private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightExpSample"

View File

@@ -32,7 +32,7 @@ import kotlinx.coroutines.withContext
class TestRightResults : Fragment() {
private lateinit var binding: FragmentTestRightResultsBinding
private val viewModel: TestRightViewModel<Any?> by activityViewModels()
private val viewModel: TestRightViewModel by activityViewModels()
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(

View File

@@ -2,6 +2,7 @@ package com.example.hpostesting.presentation.testRight
import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@@ -26,7 +27,6 @@ import com.example.hpostesting.domain.TestRightResultCalculation
import com.example.hpostesting.util.MyUtils
import com.google.firebase.storage.FirebaseStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import java.io.File
@@ -39,16 +39,14 @@ import kotlin.math.log10
import kotlin.math.pow
@HiltViewModel
@ViewModelScoped
class TestRightViewModel @Inject constructor(
private val saveRawData: SaveRawData,
private val saveRawDataTest: SaveRawDataTest,
private val repository: DatabaseRepository,
private val userDao: UserDao,
context: Context?
context: Context
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
@@ -57,10 +55,10 @@ class TestRightViewModel @Inject constructor(
val fireBaseUpload = MutableLiveData<String>()
var testDetails = DataHolder.selectedTest
val testDetails = DataHolder.selectedTest
private val _networkStatusLiveData = context?.let { NetworkStatusLiveData(it) }
val networkStatusLiveData: NetworkStatusLiveData?
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val allUserData = userDao.getAll()
@@ -442,7 +440,7 @@ class TestRightViewModel @Inject constructor(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(testDetails)) {
is Response.Success<*> -> {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
@@ -451,45 +449,43 @@ class TestRightViewModel @Inject constructor(
}
}
fun uploadResultToDatabase(context: Context, isOnline: Boolean, deviceSerialNumber: String) =
viewModelScope.launch {
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
testDetails?.csvPath = csvFilePath
testDetails?.reportPath = logTxtFilePath
testDetails?.deviceSerialNumber = deviceSerialNumber
if (isOnline) {
val storageRef = FirebaseStorage.getInstance().reference
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
fun uploadResultToDatabase(context: Context, isOnline: Boolean,deviceSerialNumber: String) = viewModelScope.launch {
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
testDetails?.csvPath = csvFilePath
testDetails?.reportPath = logTxtFilePath
testDetails?.deviceSerialNumber = deviceSerialNumber
if (isOnline) {
val storageRef = FirebaseStorage.getInstance().reference
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
try {
val csvFileUri = Uri.fromFile(File(csvFilePath))
val logTxtFileUri = Uri.fromFile(File(logTxtFilePath))
try {
val csvFileUri = Uri.fromFile(File(csvFilePath))
val logTxtFileUri = Uri.fromFile(File(logTxtFilePath))
val csvUploadTask =
storageTestDetailsRef.child(csvFileUri.lastPathSegment!!)
.putFile(csvFileUri)
.await()
val logUploadTask = storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!)
.putFile(logTxtFileUri).await()
val csvUploadTask =
storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri)
.await()
val logUploadTask = storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!)
.putFile(logTxtFileUri).await()
val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
val logUri = logUploadTask.storage.downloadUrl.await().toString()
val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber }
testDetails?.csvPath = csvUri
testDetails?.reportPath = logUri
val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
val logUri = logUploadTask.storage.downloadUrl.await().toString()
val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber }
testDetails?.csvPath = csvUri
testDetails?.reportPath = logUri
addResultTestToDb()
} catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message)
}
} else {
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
userDao.insertAll(testDetails!!)
addResultTestToDb()
} catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message)
}
} else {
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
userDao.insertAll(testDetails!!)
}
}
fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch {
val storageRef = FirebaseStorage.getInstance().reference
@@ -524,7 +520,7 @@ class TestRightViewModel @Inject constructor(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success<*> -> {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}

View File

@@ -22,7 +22,7 @@
android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:visibility="visible"
android:padding="24dp">
<TextView
@@ -57,6 +57,27 @@
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_name">
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
android:layout_width="match_parent"
@@ -66,7 +87,18 @@
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_name" />
app:layout_constraintTop_toBottomOf="@+id/til_blood_group" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order_offline"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_submit"
tools:listitem="@layout/offline_user_list_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -74,7 +106,7 @@
android:id="@+id/internetAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:visibility="gone"
android:padding="24dp">
<TextView

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/userCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/primary_light"
app:cardCornerRadius="25dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp">
<TextView
android:id="@+id/userID"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Name: MohamedKaif" />
<TextView
android:id="@+id/bloodGroup"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userID"
tools:text="UserID: MohamedKaif" />
<TextView
android:id="@+id/time"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bloodGroup"
tools:text="Test Status: Completed" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -183,8 +183,8 @@
<string name="user_list">User List</string>
<string name="user_id">User ID</string>
<string name="aadhar_id">Aadhar ID</string>
<string name="internet_not_available_please_enter_the_user_id_manually">Internet not available, please enter the user ID manually</string>
<string name="user_id_error_message">User ID should be 18 digits</string>
<string name="internet_not_available_please_enter_the_user_id_manually">Internet not available, please enter the user ID and blood group manually</string>
<string name="user_id_error_message">User ID should be 18 digits and please select the blood group</string>
<string name="upload_db_registration_title">Upload DB Registration</string>
<string name="upload_db_registration_message">Do you want to upload the local DB Registration to the cloud?</string>
<string name="upload">Upload</string>

View File

@@ -1,60 +0,0 @@
package com.example.hpostesting
import android.content.SharedPreferences
import android.view.View
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
class HemocubeViewModelTest {
@Mock
private lateinit var mockSharedPreferences: SharedPreferences
@Mock
private lateinit var mockActivity: HemocubeActivity // Replace with your actual Activity class
@Mock
private lateinit var mockBinding: FragmentHemoCubeReferenceBinding // Replace with your actual Binding class
private lateinit var hemoCubeFragment: HemoCubeFragment
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
hemoCubeFragment = HemoCubeFragment()
}
@Test
fun `handleValidResult with valid input`() {
val validString = "valid string"
val fullReadOutput = "full read output"
`when`(mockSharedPreferences.getString(anyString(), anyString())).thenReturn("dummy_value")
`when`(mockActivity.runOnUiThread(any())).thenAnswer {
val runnable = it.getArgument(0, Runnable::class.java)
runnable.run()
}
// Act
hemoCubeFragment.handleValidResult(validString, fullReadOutput)
// Assert
// Add appropriate assertions based on the behavior you expect
verify(mockSharedPreferences).edit()
verify(mockBinding).btnSubmit.visibility = View.VISIBLE
verify(mockBinding).btnSubmit.isEnabled = true
// Add more verifications as needed
}
// Add more test cases for different scenarios if needed
}

View File

@@ -1,49 +1,17 @@
package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.data.model.PatientData
import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.math.RoundingMode
import java.text.DecimalFormat
class TestRightViewModelTest {
@Mock
lateinit var mockContext: Context
@Mock
lateinit var mockRepository: DatabaseRepository
@Mock
lateinit var mockSaveRawData: SaveRawData
@Mock
lateinit var mockSaveRawDataTest: SaveRawDataTest
@Mock
lateinit var mockUserDao: UserDao
lateinit var viewModel: TestRightViewModel<Any?>
@Before
fun setUp() {
// Initialize mocks
MockitoAnnotations.initMocks(this)
// Create the ViewModel with mock dependencies
viewModel = TestRightViewModel(mockSaveRawData,mockSaveRawDataTest,mockRepository,mockUserDao,mockContext)
}
private val viewModel = TestRightViewModel()
private val data = InputData()
@Test
@@ -95,11 +63,8 @@ class TestRightViewModelTest {
viewModel.mapDeviceConstants(data.inputRead)
viewModel.mapPixelNumberToWavelength()
viewModel.mapIntensityValues(TestDataGenerator().getInputReferenceMapIntensityValues(), true)
val mapIntensityValues = viewModel.mapIntensityValues(
TestDataGenerator().getInputSampleMapIntensityValues(),
false
)
viewModel.testDetails = UserData("Surya", "2", "Male")
viewModel.mapIntensityValues(TestDataGenerator().getInputSampleMapIntensityValues(), false)
viewModel.patientDetails = PatientData("Surya", 2, "Male", TestRightResultType.UNDEFINED)
viewModel.mapWavelengthToAbsorbance()
val wavelengthList = TestDataGenerator().getOutputMapPixelNumberToWavelength()

View File

@@ -4,8 +4,8 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.0.2'
classpath 'com.google.gms:google-services:4.4.0'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1'
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.0'
}
repositories {
mavenCentral()