Files
claude bf476134c2
Some checks failed
release / build-release (push) Has been cancelled
v0.2: All videos folder, shared watched state, release-order sorting, official icon, OAuth plumbing, docs
- per-creator "All videos" folder (release order across sub-channels); sub-channel copies use
  cpost: ids and UserDataMirror keeps played/resume state in sync
- SortNameUpdater forces release-order sort names so every client lists newest first by default
- official Floatplane icon as channel image (Primary only — a channel Thumb hid video thumbnails
  in Continue Watching) and as 16:9 plugin thumbnail; one-time image replacement on upgrade
- OAuth device-flow login (FloatplaneAuthService + settings UI); needs a Floatplane client id;
  Turnstile verified domain-bound so password login inside Jellyfin is impossible
- generic install.sh (linuxserver / official image / native), thumb.png in package + manifest
- README rewritten for a general audience, doc/usage.md with screenshots, 60 tests

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-25 16:36:32 +01:00

56 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.Text.Json;
using Jellyfin.Plugin.Floatplane.Api.Models;
using Jellyfin.Plugin.Floatplane.Channel;
using Xunit;
namespace Jellyfin.Plugin.Floatplane.Tests;
public class AllVideosTests
{
[Theory]
[InlineData("post:SSvhppI28t", "SSvhppI28t")]
[InlineData("cpost:64135da7ce81077a8480c679:SSvhppI28t", "SSvhppI28t")]
[InlineData("creator:59f94c0bdd241b70349eb72b", null)]
[InlineData("all:59f94c0bdd241b70349eb72b", null)]
[InlineData("channel:a:b", null)]
[InlineData("cpost:nochannel", null)]
[InlineData("", null)]
[InlineData(null, null)]
public void PostIdOf_ParsesBothItemIdForms(string? externalId, string? expected)
{
Assert.Equal(expected, FloatplaneChannel.PostIdOf(externalId));
}
[Fact]
public void ToItem_UsesCanonicalIdByDefault_AndChannelPrefixWhenAsked()
{
var posts = Fixture.Json<List<PostModel>>("content-creator.json");
var post = posts[0];
var canonical = FloatplaneChannel.ToItem(post, null);
var inChannel = FloatplaneChannel.ToItem(post, null, true, "cpost:" + post.Channel!.Id + ":");
Assert.Equal("post:" + post.Id, canonical.Id);
Assert.Equal("cpost:" + post.Channel.Id + ":" + post.Id, inChannel.Id);
Assert.Equal(canonical.Name, inChannel.Name);
Assert.Equal(post.Id, FloatplaneChannel.PostIdOf(canonical.Id));
Assert.Equal(post.Id, FloatplaneChannel.PostIdOf(inChannel.Id));
Assert.NotEqual(FloatplaneChannel.DeterministicGuid(canonical.Id), FloatplaneChannel.DeterministicGuid(inChannel.Id));
}
}
public class SortNameTests
{
[Fact]
public void NewerReleaseSortsFirstUnderAscendingNameOrder()
{
var older = SortNameUpdater.SortNameFor(new System.DateTime(2026, 10, 1, 0, 0, 0, System.DateTimeKind.Utc));
var newer = SortNameUpdater.SortNameFor(new System.DateTime(2026, 10, 24, 18, 24, 0, System.DateTimeKind.Utc));
Assert.Equal(13, older.Length);
Assert.Equal(13, newer.Length);
Assert.True(string.CompareOrdinal(newer, older) < 0, "newer must sort before older");
Assert.Equal(13, SortNameUpdater.SortNameFor(null).Length);
}
}