Skip to content

Commit

Permalink
Merge branch 'autoresponder' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
glodanif committed Apr 8, 2018
2 parents a106639 + 189db4d commit 7b27864
Show file tree
Hide file tree
Showing 17 changed files with 545 additions and 41 deletions.
23 changes: 20 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationIdSuffix '.dev'
versionNameSuffix '-DEV'
buildConfigField "boolean", "AUTORESPONDER", "false"
}

autoresponder {
initWith(debug)
buildConfigField "boolean", "AUTORESPONDER", "true"
}

release {
Expand All @@ -68,6 +74,7 @@ android {
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "boolean", "AUTORESPONDER", "false"
}
}

Expand All @@ -81,6 +88,7 @@ dependencies {
def final SUPPORT_VERSION = '27.1.0'
def final ARCH_VERSION = '1.0.0'
def final DAGGER_VERSION = '2.4'
def final ESPRESSO_VERSION = '3.0.0'
def final COROUTINES_VERSION = '0.22.5'

implementation fileTree(dir: 'libs', include: ['*.jar'])
Expand Down Expand Up @@ -112,14 +120,23 @@ dependencies {
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"

implementation "com.android.support.test.espresso:espresso-idling-resource:$ESPRESSO_VERSION"

testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$KOTLIN_VERSION"
testImplementation 'io.mockk:mockk:1.7.10'
testImplementation 'junit:junit:4.12'

androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "com.android.support:support-annotations:$SUPPORT_VERSION"
androidTestImplementation "com.android.support.test.espresso:espresso-core:$ESPRESSO_VERSION"
androidTestImplementation("com.android.support.test.espresso:espresso-contrib:$ESPRESSO_VERSION") {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'support-v7'
exclude group: 'com.android.support', module: 'design'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
}
}

task assembleReleaseAndOpen << {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.glodanif.bluetoothchat
package com.glodanif.bluetoothchat.datasource

import android.graphics.Color
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import android.util.Log
import com.glodanif.bluetoothchat.data.entity.Conversation
import com.glodanif.bluetoothchat.data.model.ConversationsStorage
import com.glodanif.bluetoothchat.data.model.ConversationsStorageImpl
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking
import org.junit.After
import org.junit.Assert
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.glodanif.bluetoothchat.ui;

import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.content.Intent
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.RootMatchers.withDecorView
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.filters.LargeTest
import android.support.test.filters.MediumTest
import android.support.test.rule.ActivityTestRule
import android.support.test.rule.GrantPermissionRule
import android.support.test.runner.AndroidJUnit4
import com.glodanif.bluetoothchat.R
import com.glodanif.bluetoothchat.data.internal.AutoresponderProxy
import com.glodanif.bluetoothchat.ui.UITestUtils.Companion.atPosition
import com.glodanif.bluetoothchat.ui.UITestUtils.Companion.withToolbarSubTitle
import com.glodanif.bluetoothchat.ui.activity.ChatActivity
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.not
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@LargeTest
class BluetoothCommunicationInstrumentedTest {

private val autoResponderAddress = "AC:22:0B:A1:89:A8"

@Rule
@JvmField
val activityRule = ActivityTestRule(ChatActivity::class.java, true, false)

@Rule
@JvmField
val grantPermissionRule: GrantPermissionRule? = GrantPermissionRule.grant(WRITE_EXTERNAL_STORAGE)

private val textMessageDelay = 2500.toLong()
private val fileMessageDelay = 12500.toLong()
private lateinit var context: Activity

@Before
fun setup() {
activityRule.launchActivity(Intent()
.putExtra(ChatActivity.EXTRA_ADDRESS, autoResponderAddress))
context = activityRule.activity
}

@Test
fun communication() {
checkNotConnected()
checkNotSendingTextIfDisconnected()

onView(withText(R.string.chat__connect)).perform(click())
checkOutcommingConnection()

checkTextMessageReceiving()
checkTextMessageReceiving()
checkFileMessageReceiving()
checkFileMessageReceivingAndCancelByPartner()
checkFileMessageReceiving()
checkFileMessageReceivingAndCancelByPartner()
checkTextMessageReceiving()

checkDisconnectionByPartner()
onView(withId(android.R.id.button2)).perform(click())

onView(withText(R.string.chat__connect)).perform(click())
checkOutcommingConnection()

checkDisconnectionByPartner()
onView(withId(android.R.id.button1)).perform(click())
checkOutcommingConnection()

checkDisconnectionByPartner()
onView(withId(android.R.id.button2)).perform(click())

checkNotConnected()
}

private fun checkOutcommingConnection() {
onView(withText(R.string.chat__waiting_for_device))
onView(withId(R.id.tb_toolbar)).check(matches(
withToolbarSubTitle(context.getString(R.string.chat__pending))))
Thread.sleep(textMessageDelay)
onView(withId(R.id.av_actions)).check(matches(not(isDisplayed())))
onView(withId(R.id.tb_toolbar)).check(matches(
withToolbarSubTitle(context.getString(R.string.chat__connected))))
}

private fun checkFileMessageReceiving() {
onView(withId(R.id.et_message)).perform(typeText(AutoresponderProxy.COMMAND_SEND_FILE))
onView(withId(R.id.ib_send)).perform(click())
Thread.sleep(textMessageDelay)
onView(withText(R.string.chat__receiving_images)).check(matches(isDisplayed()))
Thread.sleep(fileMessageDelay)
onView(withId(R.id.rv_chat))
.check(matches(atPosition(0, hasDescendant(withId(R.id.iv_image)))))
onView(withText(R.string.chat__receiving_images)).check(matches(not(isDisplayed())))
}

private fun checkFileMessageReceivingAndCancelByPartner() {
onView(withId(R.id.et_message)).perform(typeText(AutoresponderProxy.COMMAND_SEND_FILE_AND_CANCEL))
onView(withId(R.id.ib_send)).perform(click())
Thread.sleep(textMessageDelay * 2)
onView(withText(R.string.chat__partner_canceled_image_transfer))
.inRoot(withDecorView(not(`is`(context.window.decorView)))).check(matches(isDisplayed()))
onView(withText(R.string.chat__receiving_images)).check(matches(not(isDisplayed())))
onView(withId(R.id.rv_chat))
.check(matches(atPosition(0, not(hasDescendant(withText(AutoresponderProxy.RESPONSE_RECEIVED))))))
}

private fun checkNotSendingTextIfDisconnected() {
onView(withId(R.id.et_message)).perform(typeText(AutoresponderProxy.COMMAND_SEND_TEXT))
onView(withId(R.id.ib_send)).perform(click())
onView(withText(R.string.chat__not_connected_to_send))
.inRoot(withDecorView(not(`is`(context.window.decorView)))).check(matches(isDisplayed()))
onView(withId(R.id.et_message)).perform(clearText())
}

private fun checkTextMessageReceiving() {
onView(withId(R.id.et_message)).perform(typeText(AutoresponderProxy.COMMAND_SEND_TEXT))
onView(withId(R.id.ib_send)).perform(click())
Thread.sleep(textMessageDelay)
onView(withId(R.id.rv_chat))
.check(matches(atPosition(0, hasDescendant(withText(AutoresponderProxy.RESPONSE_RECEIVED)))))
}

private fun checkDisconnectionByPartner() {
onView(withId(R.id.et_message)).perform(typeText(AutoresponderProxy.COMMAND_DISCONNECT))
onView(withId(R.id.ib_send)).perform(click())
Thread.sleep(textMessageDelay)
onView(withText(R.string.chat__partner_disconnected)).check(matches(isDisplayed()))
}

private fun checkNotConnected() {
onView(withText(R.string.chat__not_connected_to_this_device))
.check(matches(isDisplayed()))
onView(withId(R.id.tb_toolbar)).check(matches(
withToolbarSubTitle(context.getString(R.string.chat__not_connected))))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.glodanif.bluetoothchat.ui

import android.support.test.espresso.matcher.BoundedMatcher
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.view.View
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers

class UITestUtils {

companion object {

fun atPosition(position: Int, itemMatcher: Matcher<View>): Matcher<View> {

checkNotNull(itemMatcher)

return object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {

override fun describeTo(description: Description) {
description.appendText("has item at position $position: ")
itemMatcher.describeTo(description)
}

override fun matchesSafely(view: RecyclerView): Boolean {
val viewHolder = view.findViewHolderForAdapterPosition(position)
?: // has no item on such position
return false
return itemMatcher.matches(viewHolder.itemView)
}
}
}

fun withToolbarSubTitle(title: CharSequence): Matcher<View> {
return withToolbarSubTitle(Matchers.`is`(title))
}

fun withToolbarSubTitle(textMatcher: Matcher<CharSequence>): Matcher<View> {

return object : BoundedMatcher<View, Toolbar>(Toolbar::class.java) {

public override fun matchesSafely(toolbar: Toolbar): Boolean {
return textMatcher.matches(toolbar.subtitle)
}

override fun describeTo(description: Description) {
description.appendText("with toolbar title: ")
textMatcher.describeTo(description)
}
}
}
}
}
4 changes: 1 addition & 3 deletions app/src/debug/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name" translatable="false">BLC DEV</string>

</resources>
</resources>
Loading

0 comments on commit 7b27864

Please sign in to comment.