aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests/Item/ItemPersistenceServiceSaveImagesTests.cs
blob: 7997c6d771669e085a0fcbcc5a9f6b8e097048ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Server.Implementations.Item;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;

namespace Jellyfin.Server.Implementations.Tests.Item;

public class ItemPersistenceServiceSaveImagesTests : SqliteDbTestFixture
{
    private readonly ItemPersistenceService _service;

    public ItemPersistenceServiceSaveImagesTests()
    {
        _service = new ItemPersistenceService(
            CreateDbContextFactory(),
            Mock.Of<IServerApplicationHost>(),
            NullLogger<ItemPersistenceService>.Instance);
    }

    [Fact]
    public async Task SaveImagesAsync_ReplacesThePreviousImages()
    {
        var itemId = Guid.NewGuid();
        Seed(itemId);

        await _service.SaveImagesAsync(CreateItem(itemId, "/first.jpg"), TestContext.Current.CancellationToken);
        await _service.SaveImagesAsync(CreateItem(itemId, "/second.jpg"), TestContext.Current.CancellationToken);

        using var context = CreateDbContext();
        var paths = context.BaseItemImageInfos
            .Where(e => e.ItemId.Equals(itemId))
            .Select(e => e.Path)
            .ToList();

        Assert.Equal(["/second.jpg"], paths);
    }

    [Fact]
    public async Task SaveImagesAsync_ItemDeletedFromUnderIt_IsANoOp()
    {
        // A scan can delete the item between the refresh reading it and the images being written. That
        // must not fail the whole refresh, and must not leave the images of an item that is gone.
        var itemId = Guid.NewGuid();

        await _service.SaveImagesAsync(CreateItem(itemId, "/gone.jpg"), TestContext.Current.CancellationToken);

        using var context = CreateDbContext();
        Assert.Empty(context.BaseItemImageInfos.Where(e => e.ItemId.Equals(itemId)));
    }

    private static BaseItem CreateItem(Guid itemId, string imagePath)
        => new Folder
        {
            Id = itemId,
            ImageInfos = [new ItemImageInfo { Path = imagePath, Type = ImageType.Primary }]
        };

    private void Seed(Guid itemId)
    {
        using var context = CreateDbContext();
        context.BaseItems.Add(new BaseItemEntity
        {
            Id = itemId,
            Type = "Folder",
            IsFolder = true
        });
        context.SaveChanges();
    }
}