mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 15:04:50 +01:00
wip
This commit is contained in:
parent
3e394373e5
commit
c3418d0678
5 changed files with 169 additions and 174 deletions
|
@ -7,33 +7,26 @@ import android.widget.RemoteViews
|
|||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.work.testing.WorkManagerTestInitHelper
|
||||
import androidx.work.WorkManager
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.json.JSONObject
|
||||
import com.squareup.okhttp.mockwebserver.MockResponse
|
||||
import com.squareup.okhttp.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.text.NumberFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MockServerTest {
|
||||
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var context: Context
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
mockWebServer = MockWebServer()
|
||||
mockWebServer.start()
|
||||
|
||||
val baseUrl = mockWebServer.url("/").toString()
|
||||
MarketAPI.baseUrl = baseUrl
|
||||
|
||||
WorkManagerTestInitHelper.initializeTestWorkManager(context)
|
||||
MarketAPI.baseUrl = mockWebServer.url("/").toString()
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -43,45 +36,39 @@ class MockServerTest {
|
|||
|
||||
@Test
|
||||
fun testWidgetUpdate() {
|
||||
// Mock API response
|
||||
val mockResponse = MockResponse()
|
||||
.setBody(createMockJsonResponse("USD", "61500"))
|
||||
.setResponseCode(200)
|
||||
mockWebServer.enqueue(mockResponse)
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
WorkManagerTestInitHelper.initializeTestWorkManager(context)
|
||||
|
||||
val prices = listOf("60000", "60500", "61000", "61500", "62000")
|
||||
prices.forEach {
|
||||
mockWebServer.enqueue(MockResponse().setBody("""{"USD": {"price": "$it"}}"""))
|
||||
}
|
||||
|
||||
// Trigger the widget update
|
||||
WidgetUpdateWorker.scheduleWork(context)
|
||||
WorkManagerTestInitHelper.getTestDriver()?.setAllConstraintsMet(WidgetUpdateWorker.WORK_NAME)
|
||||
|
||||
// Wait for the worker to run
|
||||
val workInfos = WorkManager.getInstance(context).getWorkInfosByTag(WidgetUpdateWorker.WORK_NAME).get()
|
||||
val testDriver = WorkManagerTestInitHelper.getTestDriver()
|
||||
for (workInfo in workInfos) {
|
||||
testDriver?.setAllConstraintsMet(workInfo.id)
|
||||
}
|
||||
Thread.sleep(10000) // Wait for 10 seconds to simulate the update interval
|
||||
|
||||
// Validate the widget updates
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val widgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context, BitcoinPriceWidget::class.java))
|
||||
val thisWidget = ComponentName(context, BitcoinPriceWidget::class.java)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
|
||||
val views = RemoteViews(context.packageName, R.layout.widget_layout)
|
||||
|
||||
for (widgetId in widgetIds) {
|
||||
val views = RemoteViews(context.packageName, R.layout.widget_layout)
|
||||
// Add your assertions here to validate the widget update
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMockJsonResponse(currency: String, price: String): String {
|
||||
return """
|
||||
{
|
||||
"$currency": {
|
||||
"endPointKey": "$currency",
|
||||
"locale": "en-US",
|
||||
"source": "Kraken",
|
||||
"symbol": "$",
|
||||
"country": "United States (US Dollar)",
|
||||
"price": "$price"
|
||||
}
|
||||
prices.forEachIndexed { index, price ->
|
||||
val currencyFormat = NumberFormat.getCurrencyInstance(Locale.getDefault()).apply {
|
||||
maximumFractionDigits = 0
|
||||
}
|
||||
""".trimIndent()
|
||||
val formattedPrice = currencyFormat.format(price.toDouble())
|
||||
views.setTextViewText(R.id.price_value, formattedPrice)
|
||||
views.setTextViewText(R.id.last_updated_time, SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date()))
|
||||
|
||||
if (index > 0) {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.VISIBLE)
|
||||
views.setTextViewText(R.id.previous_price, currencyFormat.format(prices[index - 1].toDouble()))
|
||||
} else {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.GONE)
|
||||
}
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
||||
Thread.sleep(5000) // Wait for 5 seconds before updating to the next price
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,65 +8,77 @@ import android.view.View
|
|||
import android.widget.RemoteViews
|
||||
import androidx.work.*
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class WidgetUpdateWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
class WidgetUpdateWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
|
||||
|
||||
companion object {
|
||||
const val TAG = "WidgetUpdateWorker"
|
||||
const val WORK_NAME = "widget_update_work"
|
||||
const val REPEAT_INTERVAL_MINUTES = 15L
|
||||
|
||||
fun scheduleWork(context: Context) {
|
||||
val workRequest = PeriodicWorkRequestBuilder<WidgetUpdateWorker>(
|
||||
REPEAT_INTERVAL_MINUTES, TimeUnit.MINUTES
|
||||
).build()
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
WORK_NAME,
|
||||
ExistingPeriodicWorkPolicy.REPLACE,
|
||||
workRequest
|
||||
)
|
||||
Log.d(TAG, "Scheduling work for widget updates, will run every $REPEAT_INTERVAL_MINUTES minutes")
|
||||
}
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(applicationContext)
|
||||
val widgetComponent = ComponentName(applicationContext, BitcoinPriceWidget::class.java)
|
||||
val allWidgetIds = appWidgetManager.getAppWidgetIds(widgetComponent)
|
||||
Log.d(TAG, "Widget update worker running")
|
||||
|
||||
val price = MarketAPI.fetchPrice(applicationContext, "USD")
|
||||
val appWidgetManager = AppWidgetManager.getInstance(applicationContext)
|
||||
val thisWidget = ComponentName(applicationContext, BitcoinPriceWidget::class.java)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
|
||||
val views = RemoteViews(applicationContext.packageName, R.layout.widget_layout)
|
||||
|
||||
if (price != null) {
|
||||
val formattedPrice = NumberFormat.getCurrencyInstance(Locale.getDefault()).format(price.toDouble())
|
||||
// Simulate fetching price data
|
||||
val currentTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date())
|
||||
val price = fetchPrice() // Simulated method to fetch the price
|
||||
val previousPrice = getPreviousPrice() // Simulated method to fetch the previous price
|
||||
|
||||
views.setTextViewText(R.id.price_value, formattedPrice)
|
||||
views.setViewVisibility(R.id.loading_indicator, View.GONE)
|
||||
views.setViewVisibility(R.id.price_value, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.last_updated, View.VISIBLE)
|
||||
// Log fetched data
|
||||
Log.d(TAG, "Fetch completed with price: $price at $currentTime. Previous price: $previousPrice")
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val formattedTime = java.text.DateFormat.getTimeInstance().format(currentTime)
|
||||
views.setTextViewText(R.id.last_updated, "Last Updated: $formattedTime")
|
||||
// Update views
|
||||
val currencyFormat = NumberFormat.getCurrencyInstance(Locale.getDefault()).apply {
|
||||
maximumFractionDigits = 0
|
||||
}
|
||||
views.setTextViewText(R.id.price_value, currencyFormat.format(price.toDouble()))
|
||||
views.setTextViewText(R.id.last_updated_time, currentTime)
|
||||
|
||||
if (previousPrice != null) {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.VISIBLE)
|
||||
views.setTextViewText(R.id.previous_price, currencyFormat.format(previousPrice.toDouble()))
|
||||
if (price.toDouble() > previousPrice.toDouble()) {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_up_float)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_down_float)
|
||||
}
|
||||
} else {
|
||||
Log.d("WidgetUpdateWorker", "Failed to fetch price")
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.GONE)
|
||||
}
|
||||
|
||||
for (widgetId in allWidgetIds) {
|
||||
appWidgetManager.updateAppWidget(widgetId, views)
|
||||
}
|
||||
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
||||
|
||||
scheduleNextUpdate()
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private fun scheduleNextUpdate() {
|
||||
val request = OneTimeWorkRequestBuilder<WidgetUpdateWorker>()
|
||||
.setInitialDelay(10, TimeUnit.MINUTES)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(applicationContext).enqueueUniqueWork(
|
||||
"widget_update_work",
|
||||
ExistingWorkPolicy.REPLACE,
|
||||
request
|
||||
)
|
||||
|
||||
Log.d("WidgetUpdateWorker", "Scheduled next update for widget")
|
||||
private fun fetchPrice(): String {
|
||||
// Simulate a network call to fetch the price
|
||||
return (60000 + Random().nextInt(5000)).toString() // Replace with actual fetch logic
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun createWorkRequest(): OneTimeWorkRequest {
|
||||
return OneTimeWorkRequestBuilder<WidgetUpdateWorker>()
|
||||
.setInitialDelay(0, TimeUnit.SECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun scheduleWork(context: Context) {
|
||||
WorkManager.getInstance(context).enqueue(createWorkRequest())
|
||||
}
|
||||
private fun getPreviousPrice(): String? {
|
||||
// Simulate retrieving the previous price from shared preferences or a database
|
||||
return (60000 + Random().nextInt(5000)).toString() // Replace with actual retrieval logic
|
||||
}
|
||||
}
|
|
@ -1,57 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/widget_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/widget_background"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical">
|
||||
android:gravity="end">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/price_value"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loading"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
android:orientation="vertical"
|
||||
android:gravity="end">
|
||||
<TextView
|
||||
android:id="@+id/last_updated_label"
|
||||
style="@style/WidgetTextSecondary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Last Updated"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_updated"
|
||||
android:layout_width="wrap_content"
|
||||
<TextView
|
||||
android:id="@+id/last_updated_time"
|
||||
style="@style/WidgetTextPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textSize="12sp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="2dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/last_updated"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_below="@id/price_value"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="8dp"/>
|
||||
android:orientation="vertical"
|
||||
android:gravity="end">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/price_value"
|
||||
style="@style/WidgetTextPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/price_arrow_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/price_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/previous_price_label"
|
||||
style="@style/WidgetTextPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="From:"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<TextView
|
||||
android:id="@+id/previous_price"
|
||||
style="@style/WidgetTextPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textSize="12sp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/price_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/price_value"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/previous_price"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_below="@id/price_arrow"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
|
@ -2,7 +2,7 @@
|
|||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/widget_layout"
|
||||
android:minWidth="130dp"
|
||||
android:minHeight="40dp"
|
||||
android:minHeight="80dp"
|
||||
android:updatePeriodMillis="0"
|
||||
android:widgetCategory="home_screen"
|
||||
android:previewImage="@drawable/widget_preview"
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"originHash" : "52530e6b1e3a85c8854952ef703a6d1bbe1acd82713be2b3166476b9b277db23",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "bugsnag-cocoa",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/bugsnag/bugsnag-cocoa",
|
||||
"state" : {
|
||||
"revision" : "16b9145fc66e5296f16e733f6feb5d0e450574e8",
|
||||
"version" : "6.28.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "efqrcode",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/EFPrefix/EFQRCode.git",
|
||||
"state" : {
|
||||
"revision" : "2991c2f318ad9529d93b2a73a382a3f9c72c64ce",
|
||||
"version" : "6.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "keychain-swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/evgenyneu/keychain-swift.git",
|
||||
"state" : {
|
||||
"revision" : "5e1b02b6a9dac2a759a1d5dbc175c86bd192a608",
|
||||
"version" : "24.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift_qrcodejs",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ApolloZhu/swift_qrcodejs.git",
|
||||
"state" : {
|
||||
"revision" : "374dc7f7b9e76c6aeb393f6a84590c6d387e1ecb",
|
||||
"version" : "2.2.2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
Loading…
Add table
Reference in a new issue