Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue #175 retrying on Scan operation on error #174

Merged
merged 4 commits into from Apr 25, 2017

Conversation

BharathMG
Copy link
Contributor

@BharathMG BharathMG commented Apr 16, 2017

Fixes scan never getting started when retrying on failed scan operation

@BharathMG BharathMG changed the title [Bharath] Fixes issue # retrying on Scan operation on error [Bharath] Fixes issue #175 retrying on Scan operation on error Apr 16, 2017
@BharathMG BharathMG changed the title [Bharath] Fixes issue #175 retrying on Scan operation on error Fixes issue #175 retrying on Scan operation on error Apr 16, 2017
Copy link
Collaborator

@uKL uKL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a strong +1 from me. I also faced the same issue today.

@uKL uKL self-assigned this Apr 18, 2017
Copy link
Collaborator

@uKL uKL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a discussion with @dariuszseweryn I have one more thing. Could you add some tests to the behaviour?

  1. Create an observable
  2. Disable bluetooth/loction services/ets.
  3. Try subscribing and see if there's an error

And the other way. Have the Bluetooth disabled, create an observable and then enable Bluetooth.

@BharathMG
Copy link
Contributor Author

Sure @uKL . I will add it.

@uKL
Copy link
Collaborator

uKL commented Apr 18, 2017

Thanks a lot. Great job addressing this bug! :) 🥇

@uKL uKL added the bug Bug that is caused by the library label Apr 18, 2017
@BharathMG
Copy link
Contributor Author

@uKL My pleasure! Thanks for this wonderful library :)

Added a couple of tests. Let me know if I should change anything.

Copy link
Owner

@dariuszseweryn dariuszseweryn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello. Thank you for your contribution. What is needed are tests which will check that different results will be returned under different conditions. What I think is more like:

given:
// some condition is not met
def observable = objectUnderTest.scanBleDevices()
def testSubscriber0 = new TestSubscriber()
def testSubscriber1 = new TestSubscriber()

when:
observable.subscribe(testSubscriber0)

then:
testSubscriber.assertError...
// make the condition pass

when:
observable.subscribe(testSubscriber1)

then:
// check if the testSubscriber1 has no errors and everything else was called appropriately

Feel free to add tests that you think are feasible.
I will be happy to merge these changes when correct test cases will be implemented. :) 👍

bleAdapterWrapperSpy.hasBluetoothAdapter() >> true
bleAdapterWrapperSpy.isBluetoothEnabled() >> false

when:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when: should contain only one statement. In this situation scanObservable.subscribe(testSubscriber). The rest should go to given:.
Besides – it is not possible to configure mocks and spies in when:.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dariuszseweryn Will this approach be fine?

    given:
    TestSubscriber testSubscriber = new TestSubscriber<>()
    bleAdapterWrapperSpy.hasBluetoothAdapter() >> true
    bleAdapterWrapperSpy.isBluetoothEnabled() >> true

    when:
    def scanObservable = objectUnderTest.scanBleDevices(null)

    then:
    0 * bleAdapterWrapperSpy.isBluetoothEnabled()

    when:
    scanObservable.subscribe(testSubscriber)

    then:
    1 * bleAdapterWrapperSpy.startLeScan(_) >> true

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@BharathMG
Copy link
Contributor Author

BharathMG commented Apr 20, 2017

@dariuszseweryn Got it. I will make the necessary changes.

@BharathMG
Copy link
Contributor Author

Kindly check and let me know if anything is missing.

Copy link
Owner

@dariuszseweryn dariuszseweryn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is better.
I think that we could use basically one well targeted test. Check review comments.
We are getting closer. :)

@@ -79,6 +79,49 @@ class RxBleClientTest extends Specification {
1 * bleAdapterWrapperSpy.startLeScan(_) >> true
}

def "should start BLE scan if bluetooth is enabled before subscribing to the scan observable"() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description does not seem to match the test. Here it is checking if bleAdapterWrapperSpy.isBluetoothEnabled() was not called in line 92

1 * bleAdapterWrapperSpy.startLeScan(_) >> true
}

def "should start scan for only subscribers with no exceptions from scan observable"() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rephrase it to be easier to understand? Maybe something like: "should check if /condition/ is met at the time of each subscription"
It could like like this:

        given:
        def firstSubscriber = new TestSubscriber<>()
        def secondSubscriber = new TestSubscriber<>()
        bleAdapterWrapperSpy.hasBluetoothAdapter() >> true
        bleAdapterWrapperSpy.startLeScan(_) >> true
        def scanObservable = objectUnderTest.scanBleDevices(null)

        when:
        scanObservable.subscribe(firstSubscriber)

        then:
        1 * bleAdapterWrapperSpy.isBluetoothEnabled() >> false
        
        and:
        firstSubscriber.assertError {
            BleScanException exception -> exception.reason == BLUETOOTH_DISABLED
        }

        when:
        scanObservable.subscribe(secondSubscriber)

        then:
        1 * bleAdapterWrapperSpy.isBluetoothEnabled(_) >> true
        
        and:
        secondSubscriber.assertNoErrors()

Then we would need to make the test exercise for other conditions (isLocationPermissionOk / isLocationProviderOk). It could be quite easily achieved by using where: clause

Copy link
Contributor Author

@BharathMG BharathMG Apr 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Do you think this would be fine using where: ?

    def "should check if all the conditions are met at the time of each subscription"() {
    given:
    def firstSubscriber = new TestSubscriber<>()
    def secondSubscriber = new TestSubscriber<>()
    bleAdapterWrapperSpy.isBluetoothEnabled() >> bluetoothEnabled >> true
    bleAdapterWrapperSpy.hasBluetoothAdapter() >> bluetoothAvailable >> true
    locationServicesStatusMock.isLocationPermissionOk() >> locationPermissionsOk >> true
    locationServicesStatusMock.isLocationProviderOk() >> locationProviderOk >> true
    def scanObservable = objectUnderTest.scanBleDevices(null)

    when:
    scanObservable.subscribe(firstSubscriber)

    then:
    firstSubscriber.assertError {
        BleScanException exception -> exception.reason == reason
    }

    when:
    scanObservable.subscribe(secondSubscriber)

    then:
    secondSubscriber.assertNoErrors()
    1 * bleAdapterWrapperSpy.startLeScan(_) >> true

    where:
    bluetoothAvailable | bluetoothEnabled | locationPermissionsOk | locationProviderOk | reason
    false              | true             | true                  | true               | BLUETOOTH_NOT_AVAILABLE
    true               | false            | true                  | true               | BLUETOOTH_DISABLED
    true               | true             | false                 | true               | LOCATION_PERMISSION_MISSING
    true               | true             | true                  | false              | LOCATION_SERVICES_DISABLED
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. That should do. We should have also the test that would first pass and then fail (the opposite scenario).

@@ -216,6 +259,21 @@ class RxBleClientTest extends Specification {
}
}

def "should emit BleScanException if bluetooth was disabled before starting scan"() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is basically redundant to the one above and to the one at line 101

@@ -244,6 +302,21 @@ class RxBleClientTest extends Specification {
}
}

def "should emit BleScanException if location permission was not granted before starting scan"() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems also to be redundant

Copy link
Owner

@dariuszseweryn dariuszseweryn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good for me. @uKL Feel free to comment.

@dariuszseweryn dariuszseweryn merged commit a5bf7c4 into dariuszseweryn:master Apr 25, 2017
@dariuszseweryn
Copy link
Owner

@BharathMG Thank you for your support :) 👍

@BharathMG BharathMG deleted the scan-retry-fix branch April 25, 2017 13:56
@uKL
Copy link
Collaborator

uKL commented Mar 20, 2018

Dear Contributor,

similar to many open source projects we kindly request to sign our CLA if you'd like to contribute to our project. This license is for your protection as a Contributor as well as the protection of Polidea; it does not change your rights to use your own Contributions for any other purpose.

You can find a link here: https://cla-assistant.io/Polidea/RxAndroidBle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug that is caused by the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants