tauri-plugin-blec 0.14.0

BLE-Client plugin for Tauri
use std::time::Duration;

use super::helpers::*;
use crate::models::ScanFilter;

#[tokio::test(start_paused = true)]
async fn scan_finds_devices_in_range() {
    let (world, handler) = test_world();
    let device = stress_device(&world);
    let other = other_device(&world);

    let devices = scan(handler, ScanFilter::None).await.unwrap();
    let addresses: Vec<_> = devices.iter().map(|d| d.address.clone()).collect();
    assert_eq!(devices.len(), 2, "{addresses:?}");
    assert!(addresses.contains(&device.address_string()));
    assert!(addresses.contains(&other.address_string()));

    let stress = devices
        .iter()
        .find(|d| d.address == device.address_string())
        .unwrap();
    assert_eq!(stress.name, "stress");
    assert_eq!(stress.services, vec![SERVICE, SERVICE2]);
    assert_eq!(
        stress.manufacturer_data.get(&MANUFACTURER_ID),
        Some(&MANUFACTURER_DATA.to_vec())
    );
    assert!(!stress.is_connected);
    assert!(!world.is_scanning(), "scan was not stopped on the adapter");
}

#[tokio::test(start_paused = true)]
async fn out_of_range_device_is_not_found() {
    let (world, handler) = test_world();
    let device = stress_device(&world);
    let other = other_device(&world);
    device.set_in_range(false);

    let devices = scan(handler, ScanFilter::None).await.unwrap();
    assert_eq!(devices.len(), 1);
    assert_eq!(devices[0].address, other.address_string());

    device.set_in_range(true);
    let devices = scan(handler, ScanFilter::None).await.unwrap();
    assert_eq!(devices.len(), 2);
}

#[tokio::test(start_paused = true)]
async fn scan_filters() {
    let (world, handler) = test_world();
    let device = stress_device(&world);
    let _other = other_device(&world);

    let only_stress = |devices: Vec<crate::models::BleDevice>| {
        assert_eq!(devices.len(), 1, "{devices:?}");
        assert_eq!(devices[0].address, device.address_string());
    };

    only_stress(scan(handler, ScanFilter::Service(SERVICE)).await.unwrap());
    only_stress(
        scan(
            handler,
            ScanFilter::AnyService(vec![SERVICE2, CHARAC_MISSING]),
        )
        .await
        .unwrap(),
    );
    only_stress(
        scan(handler, ScanFilter::AllServices(vec![SERVICE, SERVICE2]))
            .await
            .unwrap(),
    );
    only_stress(
        scan(
            handler,
            ScanFilter::ManufacturerData(MANUFACTURER_ID, MANUFACTURER_DATA.to_vec()),
        )
        .await
        .unwrap(),
    );
    only_stress(
        scan(
            handler,
            ScanFilter::ManufacturerDataMasked(
                MANUFACTURER_ID,
                vec![0x21, 0x00, 0x00, 0x00],
                vec![0xff, 0x00, 0x00, 0x00],
            ),
        )
        .await
        .unwrap(),
    );

    assert!(scan(handler, ScanFilter::Service(CHARAC_MISSING))
        .await
        .unwrap()
        .is_empty());
    assert!(scan(
        handler,
        ScanFilter::ManufacturerData(MANUFACTURER_ID, vec![0x00, 0x00, 0x00, 0x00])
    )
    .await
    .unwrap()
    .is_empty());
    assert!(matches!(
        handler
            .discover(
                None,
                100,
                ScanFilter::ManufacturerDataMasked(MANUFACTURER_ID, vec![1], vec![1, 2]),
                false
            )
            .await,
        Err(crate::error::Error::InvalidFilterMask)
    ));
}

#[tokio::test(start_paused = true)]
async fn scanning_state_is_reported() {
    let (world, handler) = test_world();
    let _device = stress_device(&world);
    let mut updates = scanning_updates(handler).await;

    handler
        .discover(None, 400, ScanFilter::None, false)
        .await
        .unwrap();
    assert!(handler.is_scanning().await);
    assert!(world.is_scanning());
    assert_eq!(drain(&mut updates), vec![true]);

    assert!(wait_until(Duration::from_secs(5), || !world.is_scanning()).await);
    settle().await;
    assert!(!handler.is_scanning().await);
    assert_eq!(drain(&mut updates), vec![false]);
}

#[tokio::test(start_paused = true)]
async fn stop_scan_ends_scan_early() {
    let (world, handler) = test_world();
    let _device = stress_device(&world);
    let mut updates = scanning_updates(handler).await;

    handler
        .discover(None, 60_000, ScanFilter::None, false)
        .await
        .unwrap();
    settle().await;
    assert!(world.is_scanning());
    handler.stop_scan().await.unwrap();
    settle().await;
    assert!(!world.is_scanning());
    assert!(!handler.is_scanning().await);
    assert_eq!(drain(&mut updates), vec![true, false]);
}

#[tokio::test(start_paused = true)]
async fn second_scan_replaces_first() {
    let (world, handler) = test_world();
    let _device = stress_device(&world);

    handler
        .discover(None, 60_000, ScanFilter::None, false)
        .await
        .unwrap();
    settle().await;
    let devices = scan(handler, ScanFilter::None).await.unwrap();
    assert_eq!(devices.len(), 1);
    assert!(!world.is_scanning());
    assert!(!handler.is_scanning().await);
}