Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
awasisto committed Apr 18, 2021
2 parents bc81ca0 + 76b3f3c commit 9449cf4
Show file tree
Hide file tree
Showing 19 changed files with 73 additions and 29 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
CamRNG HTTP
===========

An HTTP API for [CamRNG](https://github.com/awasisto/camrng) quantum random number generator.
An HTTP API server for [CamRNG](https://github.com/awasisto/camrng) quantum random number generator.

Screenshots
-----------

![CamRNG HTTP screenshot 1](https://lh3.googleusercontent.com/vjYA8K0jdwoIst_mibni7EQkhV3pMs_RBDyHXCiZNKhj1mU09Ib2Hi2oLZWNy2RUEI7V=w250-rw)
![CamRNG HTTP screenshot 2](https://lh3.googleusercontent.com/m8E0Et3TMRamPdRgr8d7x_fbGMRiZBNWhS6lzhe2v6kr3EPmfdXC63ZvcNqXiWG2oVts=w250-rw)

API Documentation
-----------------
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ android {
applicationId "com.wasisto.camrnghttp"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "0.0.1"
versionCode 2
versionName "0.0.2"
}

buildFeatures {
Expand Down
1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:fullBackupContent="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ package com.wasisto.camrnghttp.server.api

import com.google.gson.Gson
import com.koushikdutta.async.http.server.AsyncHttpServerResponse
import timber.log.Timber

class ErrorHandler {

private val gson = Gson()

fun handle(throwable: Throwable, response: AsyncHttpServerResponse) {
when(throwable) {
fun handle(t: Throwable, response: AsyncHttpServerResponse) {
when(t) {
is IllegalArgumentException -> {
response.code(422).send(
CONTENT_TYPE_JSON, gson.toJson(mapOf(
Pair(JSON_ATTRIBUTE_MESSAGE, ERROR_VALIDATION_FAILED)
)))
}
else -> {
Timber.w(t)
response.code(500).send(
CONTENT_TYPE_JSON, gson.toJson(mapOf(
Pair(JSON_ATTRIBUTE_MESSAGE, ERROR_SERVER_ERROR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ class CamrngRandomDataSource(private val context: Context) : RandomDataSource {

fun stop() {
NoiseBasedCamRng.reset()
byteIterator = null
}

override fun randBytes(bytes: ByteArray) {
for (i in bytes.indices) bytes[i] = byteIterator!!.next()
byteIterator?.let { for (i in bytes.indices) bytes[i] = it.next() } ?: throw IllegalStateException()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.wasisto.camrnghttp.servermanager.domain.interfaces.Server
import com.wasisto.camrnghttp.servermanager.domain.usecases.StartServerUseCase
import com.wasisto.camrnghttp.servermanager.domain.usecases.StopServerUseCase
import com.wasisto.camrnghttp.servermanager.ui.main.MainViewModel
import kotlinx.coroutines.Dispatchers

class ViewModelFactory(private val server: Server) : ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
Expand All @@ -34,9 +33,7 @@ class ViewModelFactory(private val server: Server) : ViewModelProvider.NewInstan
MainViewModel(
StartServerUseCase(server),
StopServerUseCase(server),
GetServerIpAddressUseCase(server),
Dispatchers.IO,
Dispatchers.Main
GetServerIpAddressUseCase(server)
)
else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ import com.wasisto.camrnghttp.servermanager.domain.usecases.StartServerUseCase
import com.wasisto.camrnghttp.servermanager.domain.usecases.StopServerUseCase
import com.wasisto.camrnghttp.servermanager.ui.Event
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber

class MainViewModel(
private val startServerUseCase: StartServerUseCase,
private val stopServerUseCase: StopServerUseCase,
private val getServerIpAddressUseCase: GetServerIpAddressUseCase,
private val ioDispatcher: CoroutineDispatcher,
private val mainDispatcher: CoroutineDispatcher
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val mainDispatcher: CoroutineDispatcher = Dispatchers.Main
) : ViewModel() {

val ipAddress = MutableLiveData<String>()
Expand Down
Binary file modified app/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary file not shown.
Binary file modified app/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
43 changes: 43 additions & 0 deletions app/src/test/java/com/wasisto/camrnghttp/MainCoroutineRule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2021 Andika Wasisto
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.wasisto.camrnghttp

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description

@ExperimentalCoroutinesApi
class MainCoroutineRule(
val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
): TestWatcher(), TestCoroutineScope by TestCoroutineScope(dispatcher) {

override fun starting(description: Description?) {
super.starting(description)
Dispatchers.setMain(dispatcher)
}

override fun finished(description: Description?) {
super.finished(description)
cleanupTestCoroutines()
Dispatchers.resetMain()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.wasisto.camrnghttp.servermanager.ui.main

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.wasisto.camrnghttp.MainCoroutineRule
import com.wasisto.camrnghttp.R
import com.wasisto.camrnghttp.servermanager.domain.usecases.GetServerIpAddressUseCase
import com.wasisto.camrnghttp.servermanager.domain.usecases.StartServerUseCase
Expand All @@ -27,8 +28,8 @@ import io.mockk.impl.annotations.MockK
import io.mockk.verify
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
Expand All @@ -51,7 +52,8 @@ class MainViewModelTest {
@MockK
private lateinit var getServerIpAddressUseCase: GetServerIpAddressUseCase

private val testCoroutineDispatcher = TestCoroutineDispatcher()
@get:Rule
var coroutineRule = MainCoroutineRule()

@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
Expand All @@ -63,20 +65,13 @@ class MainViewModelTest {
startServerUseCase,
stopServerUseCase,
getServerIpAddressUseCase,
testCoroutineDispatcher,
testCoroutineDispatcher
coroutineRule.dispatcher,
coroutineRule.dispatcher
)
Dispatchers.setMain(testCoroutineDispatcher)
}

@After
fun tearDown() {
Dispatchers.resetMain()
testCoroutineDispatcher.cleanupTestCoroutines()
}

@Test
fun testOnStartStopButtonClick_startServer() {
fun testOnStartStopButtonClick_startServer() = coroutineRule.runBlockingTest {
val serverIpAddress = "192.168.1.100"
val port = 8080

Expand All @@ -93,7 +88,7 @@ class MainViewModelTest {
}

@Test
fun testOnStartStopButtonClick_startServer_error() {
fun testOnStartStopButtonClick_startServer_error() = coroutineRule.runBlockingTest {
val port = 8080

every { startServerUseCase(any()) }.throws(Exception())
Expand All @@ -109,7 +104,7 @@ class MainViewModelTest {
}

@Test
fun testOnStartStopButtonClick_stopServer() {
fun testOnStartStopButtonClick_stopServer() = coroutineRule.runBlockingTest {
testOnStartStopButtonClick_startServer()

mainViewModel.onStartStopButtonClick()
Expand All @@ -122,7 +117,7 @@ class MainViewModelTest {
}

@Test
fun testOnStartStopButtonClick_stopServer_error() {
fun testOnStartStopButtonClick_stopServer_error() = coroutineRule.runBlockingTest {
testOnStartStopButtonClick_startServer()

every { stopServerUseCase() }.throws(Exception())
Expand All @@ -137,7 +132,7 @@ class MainViewModelTest {
}

@Test
fun testOnActivityStopped() {
fun testOnActivityStopped() = coroutineRule.runBlockingTest {
mainViewModel.onActivityStopped()
verify { stopServerUseCase() }
}
Expand Down

0 comments on commit 9449cf4

Please sign in to comment.