Shakeout Testing Part 1 (#1052)

* Have language from epubs populate metadata

* series detail needs to reload the underlying volumes when scan event comes in, not just metadata.

* Added Id to chapter detail modal (for debugging)

* Implement IDisposable on applicable Unit Tests

* Removed unused using statements

* Fixed a bug where images would flash like crazy during a scan because the code to refresh the underlying image wasn't checking the entity type or Id.

* When filtering rating, only apply the filter to your account.

* Removed Disposable on tests
This commit is contained in:
Joseph Milazzo 2022-02-09 16:59:14 -08:00 committed by GitHub
parent 1f8f6f6fac
commit 2b0d47d15e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 102 additions and 49 deletions

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.IO.Abstractions.TestingHelpers;
@ -10,15 +11,11 @@ using API.DTOs.Reader;
using API.Entities;
using API.Entities.Enums;
using API.Services;
using API.Services.Tasks;
using API.SignalR;
using AutoMapper;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Logging;
using NetVips;
using NSubstitute;
using Xunit;
@ -26,10 +23,7 @@ namespace API.Tests.Services;
public class BookmarkServiceTests
{
private readonly ILogger<CleanupService> _logger = Substitute.For<ILogger<CleanupService>>();
private readonly IUnitOfWork _unitOfWork;
private readonly IHubContext<MessageHub> _messageHub = Substitute.For<IHubContext<MessageHub>>();
private readonly DbConnection _connection;
private readonly DataContext _context;
@ -63,8 +57,6 @@ public class BookmarkServiceTests
return connection;
}
public void Dispose() => _connection.Dispose();
private async Task<bool> SeedDb()
{
await _context.Database.MigrateAsync();

View File

@ -61,8 +61,6 @@ public class CleanupServiceTests
return connection;
}
public void Dispose() => _connection.Dispose();
private async Task<bool> SeedDb()
{
await _context.Database.MigrateAsync();

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
@ -95,8 +96,6 @@ public class ParseScannedFilesTests
return connection;
}
public void Dispose() => _connection.Dispose();
private async Task<bool> SeedDb()
{
await _context.Database.MigrateAsync();

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
@ -10,10 +11,8 @@ using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Services;
using API.SignalR;
using API.Tests.Helpers;
using AutoMapper;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -25,9 +24,8 @@ namespace API.Tests.Services;
public class ReaderServiceTests
{
private readonly ILogger<CacheService> _logger = Substitute.For<ILogger<CacheService>>();
private readonly IUnitOfWork _unitOfWork;
private readonly IHubContext<MessageHub> _messageHub = Substitute.For<IHubContext<MessageHub>>();
private readonly DbConnection _connection;
private readonly DataContext _context;
@ -61,8 +59,6 @@ public class ReaderServiceTests
return connection;
}
public void Dispose() => _connection.Dispose();
private async Task<bool> SeedDb()
{
await _context.Database.MigrateAsync();
@ -902,6 +898,81 @@ public class ReaderServiceTests
Assert.Equal(-1, prevChapter);
}
[Fact]
public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromVolumeWithZeroChapter()
{
await ResetDB();
_context.Series.Add(new Series()
{
Name = "Test",
Library = new Library() {
Name = "Test LIb",
Type = LibraryType.Manga,
},
Volumes = new List<Volume>()
{
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("0", false, new List<MangaFile>()),
}),
}
});
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007"
});
await _context.SaveChangesAsync();
var readerService = new ReaderService(_unitOfWork, Substitute.For<ILogger<ReaderService>>());
var prevChapter = await readerService.GetPrevChapterIdAsync(1, 1, 1, 1);
Assert.Equal(-1, prevChapter);
}
[Fact]
public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromVolumeWithZeroChapterAndHasNormalChapters()
{
await ResetDB();
_context.Series.Add(new Series()
{
Name = "Test",
Library = new Library() {
Name = "Test LIb",
Type = LibraryType.Manga,
},
Volumes = new List<Volume>()
{
EntityFactory.CreateVolume("0", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false, new List<MangaFile>()),
EntityFactory.CreateChapter("2", false, new List<MangaFile>()),
}),
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("0", false, new List<MangaFile>()),
}),
}
});
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007"
});
await _context.SaveChangesAsync();
var readerService = new ReaderService(_unitOfWork, Substitute.For<ILogger<ReaderService>>());
var prevChapter = await readerService.GetPrevChapterIdAsync(1, 1, 1, 1);
Assert.Equal(-1, prevChapter);
}
[Fact]
public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromChapter()
{

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.Immutable;
namespace API.Constants
{

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.Data;
using API.DTOs;
using API.DTOs.Reader;
using API.Entities.Enums;
using API.Extensions;

View File

@ -156,7 +156,7 @@ namespace API.Controllers
{
tag.CoverImageLocked = false;
tag.CoverImage = string.Empty;
await _messageHub.Clients.All.SendAsync(SignalREvents.CoverUpdate, MessageFactory.CoverUpdateEvent(tag.Id, "collection"));
await _messageHub.Clients.All.SendAsync(SignalREvents.CoverUpdate, MessageFactory.CoverUpdateEvent(tag.Id, "collectionTag"));
_unitOfWork.CollectionTagRepository.Update(tag);
}

View File

@ -8,7 +8,6 @@ using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Reader;
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Services;
using API.Services.Tasks;

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using API.DTOs.Stats;
using API.DTOs.Update;

View File

@ -1,6 +1,4 @@
using System.ComponentModel.DataAnnotations;
namespace API.DTOs.Account;
namespace API.DTOs.Account;
public class MigrateUserEmailDto
{

View File

@ -2,7 +2,6 @@
using API.DTOs.CollectionTags;
using API.DTOs.Metadata;
using API.DTOs.ReadingLists;
using API.Entities;
namespace API.DTOs.Search;

View File

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

View File

@ -636,7 +636,7 @@ public class SeriesRepository : ISeriesRepository
&& (!hasPeopleFilter || s.Metadata.People.Any(p => allPeopleIds.Contains(p.Id)))
&& (!hasCollectionTagFilter ||
s.Metadata.CollectionTags.Any(t => filter.CollectionTags.Contains(t.Id)))
&& (!hasRatingFilter || s.Ratings.Any(r => r.Rating >= filter.Rating))
&& (!hasRatingFilter || s.Ratings.Any(r => r.Rating >= filter.Rating && r.AppUserId == userId))
&& (!hasProgressFilter || seriesIds.Contains(s.Id))
&& (!hasAgeRating || filter.AgeRating.Contains(s.Metadata.AgeRating))
&& (!hasTagsFilter || s.Metadata.Tags.Any(t => filter.Tags.Contains(t.Id)))

View File

@ -2,7 +2,6 @@
using System.Linq;
using API.DTOs;
using API.DTOs.CollectionTags;
using API.DTOs.Email;
using API.DTOs.Metadata;
using API.DTOs.Reader;
using API.DTOs.ReadingLists;

View File

@ -388,6 +388,7 @@ namespace API.Services
Year = !string.IsNullOrEmpty(publicationDate) ? DateTime.Parse(publicationDate).Year : 0,
Title = epubBook.Title,
Genre = string.Join(",", epubBook.Schema.Package.Metadata.Subjects.Select(s => s.ToLower().Trim())),
LanguageISO = epubBook.Schema.Package.Metadata.Languages.FirstOrDefault() ?? string.Empty
};
// Parse tags not exposed via Library

View File

@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using API.Data;
using API.Data.Repositories;
using API.DTOs.Reader;
using API.Entities;
using API.Entities.Enums;

View File

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
@ -7,7 +6,6 @@ using System.IO.Abstractions;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using API.Comparators;
using API.Extensions;
using Microsoft.Extensions.Logging;

View File

@ -6,7 +6,6 @@ using System.Threading.Tasks;
using API.Comparators;
using API.Data;
using API.Data.Repositories;
using API.Data.Scanner;
using API.Entities;
using API.Extensions;
using API.Helpers;

View File

@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using API.Data;

View File

@ -1,5 +1,4 @@
using System;
using System.Threading;
using API.DTOs.Update;
namespace API.SignalR

View File

@ -3,5 +3,5 @@
*/
export interface CoverUpdateEvent {
id: number;
entityType: 'series' | 'chapter' | 'volume' | 'collection';
entityType: 'series' | 'chapter' | 'volume' | 'collectionTag';
}

View File

@ -4,7 +4,11 @@
<!-- Arc Information -->
<div class="row no-gutters">
<div class="col">
Id: {{chapter.id}}
</div>
</div>
<div class="row no-gutters">
<div class="col">

View File

@ -203,10 +203,7 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
} else if (event.event === EVENTS.ScanSeries) {
const seriesCoverUpdatedEvent = event.payload as ScanSeriesEvent;
if (seriesCoverUpdatedEvent.seriesId === this.series.id) {
this.seriesService.getMetadata(this.series.id).pipe(take(1)).subscribe(metadata => {
this.seriesMetadata = metadata;
this.createHTML();
});
this.loadSeries(seriesId);
}
}
});

View File

@ -1,6 +1,7 @@
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CoverUpdateEvent } from 'src/app/_models/events/cover-update-event';
import { ImageService } from 'src/app/_services/image.service';
import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';
@ -46,7 +47,13 @@ export class ImageComponent implements OnChanges, OnDestroy {
constructor(public imageService: ImageService, private renderer: Renderer2, private hubService: MessageHubService) {
this.hubService.messages$.pipe(takeUntil(this.onDestroy)).subscribe(res => {
if (res.event === EVENTS.CoverUpdate) {
this.imageUrl = this.imageService.randomize(this.imageUrl);
const updateEvent = res.payload as CoverUpdateEvent;
if (this.imageUrl === undefined || this.imageUrl === null || this.imageUrl === '') return;
const tokens = this.imageUrl.split(updateEvent.entityType + 'Id=');
if (tokens.length > 1 && tokens[1] === (updateEvent.id + '')) {
this.imageUrl = this.imageService.randomize(this.imageUrl);
}
}
});
}