refactor(qconnect): tighten cast-predicate test, dedupe test fixture, document shared-gate intent
Cross-check test now pins admission to is_castable_to_qconnect (incl. OfflineCache) instead of the streamable predicate. Dedupe the queuePlaybackService test builder. Document is_castable_to_qconnect/from_source_str_strict/TrackOriginTag as the shared QConnect-admission gate consumed by the Slint port. cc
This commit is contained in:
3 files changed
+14
-9
No files matched your search
@@ -64,6 +64,9 @@ impl PlaybackSource {
|
|||||||
/// The admission-side cast predicate. Offline-cache maps to castable (the
|
/// The admission-side cast predicate. Offline-cache maps to castable (the
|
||||||
/// offline copy carries a valid Qobuz track id). This is the method the
|
/// offline copy carries a valid Qobuz track id). This is the method the
|
||||||
/// QConnect gate consults; is_qobuz_streamable stays "streams live from Qobuz".
|
/// QConnect gate consults; is_qobuz_streamable stays "streams live from Qobuz".
|
||||||
|
///
|
||||||
|
/// Shared QConnect-admission gate primitive: this is the single predicate
|
||||||
|
/// both the Tauri and the upcoming Slint frontends call to gate casting.
|
||||||
pub fn is_castable_to_qconnect(self) -> bool {
|
pub fn is_castable_to_qconnect(self) -> bool {
|
||||||
matches!(self, Self::Qobuz | Self::OfflineCache)
|
matches!(self, Self::Qobuz | Self::OfflineCache)
|
||||||
}
|
}
|
||||||
@@ -71,6 +74,9 @@ impl PlaybackSource {
|
|||||||
|
|
||||||
/// Admission-only origin tag. Unlike PlaybackSource, this has ExternalUnknown
|
/// Admission-only origin tag. Unlike PlaybackSource, this has ExternalUnknown
|
||||||
/// so the Qobuz Connect gate can default unknown/absent to *blocked* not *Qobuz*.
|
/// so the Qobuz Connect gate can default unknown/absent to *blocked* not *Qobuz*.
|
||||||
|
///
|
||||||
|
/// Shared QConnect-admission gate primitive consumed by the Slint port (its
|
||||||
|
/// strict-parse companion for the cast gate); kept intentionally for that use.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum TrackOriginTag {
|
pub enum TrackOriginTag {
|
||||||
Qobuz,
|
Qobuz,
|
||||||
@@ -82,6 +88,9 @@ pub enum TrackOriginTag {
|
|||||||
|
|
||||||
impl PlaybackSource {
|
impl PlaybackSource {
|
||||||
/// Strict parse for the admission path: unknown/absent → ExternalUnknown (blocked).
|
/// Strict parse for the admission path: unknown/absent → ExternalUnknown (blocked).
|
||||||
|
///
|
||||||
|
/// Shared QConnect-admission gate primitive consumed by the Slint port (it
|
||||||
|
/// feeds the cast gate, where unknown origins must block, not default to Qobuz).
|
||||||
pub fn from_source_str_strict(s: Option<&str>) -> TrackOriginTag {
|
pub fn from_source_str_strict(s: Option<&str>) -> TrackOriginTag {
|
||||||
match s {
|
match s {
|
||||||
Some("qobuz") => TrackOriginTag::Qobuz,
|
Some("qobuz") => TrackOriginTag::Qobuz,
|
||||||
|
|||||||
@@ -68,16 +68,17 @@ mod tests {
|
|||||||
use qbz_models::PlaybackSource;
|
use qbz_models::PlaybackSource;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn admission_matches_playback_source_predicate() {
|
fn admission_matches_cast_predicate() {
|
||||||
let pairs = [
|
let pairs = [
|
||||||
(TrackOrigin::QobuzOnline, PlaybackSource::Qobuz),
|
(TrackOrigin::QobuzOnline, PlaybackSource::Qobuz),
|
||||||
|
(TrackOrigin::QobuzOfflineCache, PlaybackSource::OfflineCache),
|
||||||
(TrackOrigin::LocalLibrary, PlaybackSource::Local),
|
(TrackOrigin::LocalLibrary, PlaybackSource::Local),
|
||||||
(TrackOrigin::Plex, PlaybackSource::Plex),
|
(TrackOrigin::Plex, PlaybackSource::Plex),
|
||||||
];
|
];
|
||||||
for (origin, source) in pairs {
|
for (origin, source) in pairs {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
evaluate_remote_queue_admission(origin).accepted,
|
evaluate_remote_queue_admission(origin).accepted,
|
||||||
source.is_qobuz_streamable(),
|
source.is_castable_to_qconnect(),
|
||||||
"admission/predicate disagree for {origin:?}",
|
"admission/predicate disagree for {origin:?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,21 +67,16 @@ describe('assessQconnectQueueSync', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const track = (over: Partial<BackendQueueTrack>): BackendQueueTrack =>
|
|
||||||
({ id: 1, title: 't', artist: 'a', album: 'al', duration_secs: 0, artwork_url: null,
|
|
||||||
hires: false, bit_depth: null, sample_rate: null, is_local: false, album_id: null,
|
|
||||||
artist_id: null, streamable: true, source: 'qobuz', parental_warning: false, ...over }) as BackendQueueTrack;
|
|
||||||
|
|
||||||
describe('assessQconnectQueueSync — offline-cache', () => {
|
describe('assessQconnectQueueSync — offline-cache', () => {
|
||||||
it('treats qobuz_download as syncable (offline copy carries a Qobuz id)', () => {
|
it('treats qobuz_download as syncable (offline copy carries a Qobuz id)', () => {
|
||||||
const r = assessQconnectQueueSync([track({ id: 5, source: 'qobuz_download' })]);
|
const r = assessQconnectQueueSync([buildTrack(5, { source: 'qobuz_download' })]);
|
||||||
expect(r.syncable).toBe(true);
|
expect(r.syncable).toBe(true);
|
||||||
expect(r.trackIds).toEqual([5]);
|
expect(r.trackIds).toEqual([5]);
|
||||||
expect(r.blockedTrackIds).toEqual([]);
|
expect(r.blockedTrackIds).toEqual([]);
|
||||||
});
|
});
|
||||||
it('still blocks local and plex', () => {
|
it('still blocks local and plex', () => {
|
||||||
const r = assessQconnectQueueSync([
|
const r = assessQconnectQueueSync([
|
||||||
track({ id: 1, source: 'qobuz' }), track({ id: 2, source: 'local' }),
|
buildTrack(1, { source: 'qobuz' }), buildTrack(2, { source: 'local' }),
|
||||||
]);
|
]);
|
||||||
expect(r.syncable).toBe(false);
|
expect(r.syncable).toBe(false);
|
||||||
expect(r.blockedTrackIds).toContain(2);
|
expect(r.blockedTrackIds).toContain(2);
|
||||||
|
|||||||
Reference in new issue
Block a user