Skip to content

Commit

Permalink
Merge pull request #933 from dlcs/feature/nq_batch
Browse files Browse the repository at this point in the history
Handle NQ 'batch' parameter
  • Loading branch information
donaldgray authored Jan 10, 2025
2 parents 0da9d18 + 4bfc054 commit 06c4236
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/protagonist/DLCS.Core/Strings/StringX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ string DomainMapper(Match match)
/// <param name="str">String to split</param>
/// <param name="separator">String to split by.</param>
/// <returns>String split, or empty list.</returns>
public static IEnumerable<string> SplitSeparatedString(this string str, string separator)
public static IEnumerable<string> SplitSeparatedString(this string? str, string separator)
=> str?.Trim().Split(separator, StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty<string>();

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace DLCS.Model.Assets.NamedQueries;
public class ParsedNamedQuery
{
/// <summary>
/// Collection of OrderBy clauses to apply to assets.
/// Collection of OrderBy clauses to apply to assets
/// </summary>
public List<QueryOrder> AssetOrdering { get; set; } = new() { new QueryOrder(QueryMapping.Unset) };

Expand Down Expand Up @@ -54,6 +54,11 @@ public class ParsedNamedQuery
/// </summary>
public long? Number3 { get; set; }

/// <summary>
/// Value of "batches" after parsing
/// </summary>
public int[]? Batches { get; set; }

/// <summary>
/// The name of the namedQuery this object was parsed from.
/// </summary>
Expand Down Expand Up @@ -99,7 +104,7 @@ public enum QueryMapping
String3,
Number1,
Number2,
Number3
Number3,
}

public enum OrderDirection
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Linq;
using DLCS.Core.Caching;
using DLCS.Core.Caching;
using DLCS.Core.Types;
using DLCS.Model.Assets;
using DLCS.Model.Assets.NamedQueries;
using DLCS.Repository.Assets;
using LazyCache.Mocks;
Expand All @@ -14,12 +14,11 @@ namespace DLCS.Repository.Tests.NamedQueries;
[Collection(DatabaseCollection.CollectionName)]
public class NamedQueryRepositoryTests
{
private readonly DlcsContext dbContext;
private readonly NamedQueryRepository sut;

public NamedQueryRepositoryTests(DlcsDatabaseFixture dbFixture)
{
dbContext = dbFixture.DbContext;
var dbContext = dbFixture.DbContext;
sut = new NamedQueryRepository(dbFixture.DbContext, new MockCachingService(),
Options.Create(new CacheSettings()));

Expand All @@ -38,6 +37,26 @@ public NamedQueryRepositoryTests(DlcsDatabaseFixture dbFixture)
dbContext.Images.AddTestAsset(AssetId.FromString("99/1/7"), space: 2);
dbContext.Images.AddTestAsset(AssetId.FromString("99/1/8"), ref1: "foo", ref2: "bar", ref3: "baz", num1: 5,
num2: 10, num3: 20);

// Batch records - first with 3 and second with 2. 1 asset is in both
var batchedAsset1 = AssetId.FromString("99/2/1");
var batchedAsset2 = AssetId.FromString("99/2/2");
var batchedAsset3 = AssetId.FromString("99/2/3");
var batchedAsset4 = AssetId.FromString("99/2/4");
const int batchId1 = 101010;
const int batchId2 = 101011;
dbContext.Images.AddTestAsset(batchedAsset1, space: 2);
dbContext.Images.AddTestAsset(batchedAsset2, space: 2, num3: 1);
dbContext.Images.AddTestAsset(batchedAsset3, space: 2, num3: 1);
dbContext.Images.AddTestAsset(batchedAsset4, space: 2, num3: 1);
var batch = dbContext.Batches.AddTestBatch(batchId1).Result;
batch.Entity
.AddBatchAsset(batchedAsset1)
.AddBatchAsset(batchedAsset2, BatchAssetStatus.Completed)
.AddBatchAsset(batchedAsset3, BatchAssetStatus.Error);

var batch2 = dbContext.Batches.AddTestBatch(batchId2).Result;
batch2.Entity.AddBatchAsset(batchedAsset1).AddBatchAsset(batchedAsset4);
dbContext.SaveChanges();
}

Expand Down Expand Up @@ -119,7 +138,7 @@ public async Task GetNamedQueryResults_ReturnsAllForCustomer_IfNoOtherCriteria()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Count().Should().Be(8);
result.Should().HaveCount(12);
}

[Fact]
Expand All @@ -135,7 +154,7 @@ public async Task GetNamedQueryResults_FilterByString1()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/1"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/1"));
}

[Fact]
Expand All @@ -151,7 +170,7 @@ public async Task GetNamedQueryResults_FilterByString2()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/2"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/2"));
}

[Fact]
Expand All @@ -167,7 +186,7 @@ public async Task GetNamedQueryResults_FilterByString3()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/3"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/3"));
}

[Fact]
Expand All @@ -183,7 +202,7 @@ public async Task GetNamedQueryResults_FilterByNumber1()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/4"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/4"));
}

[Fact]
Expand All @@ -199,7 +218,7 @@ public async Task GetNamedQueryResults_FilterByNumber2()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/5"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/5"));
}

[Fact]
Expand All @@ -215,7 +234,7 @@ public async Task GetNamedQueryResults_FilterByNumber3()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/6"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/6"));
}

[Fact]
Expand All @@ -231,7 +250,7 @@ public async Task GetNamedQueryResults_FilterBySpace()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Count().Should().Be(7);
result.Should().HaveCount(7);
}

[Fact]
Expand All @@ -247,7 +266,7 @@ public async Task GetNamedQueryResults_FilterBySpaceName()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Count().Should().Be(7);
result.Should().HaveCount(7);
}

[Fact]
Expand All @@ -263,7 +282,7 @@ public async Task GetNamedQueryResults_FilterBySpaceAndSpaceName_SpaceTakesPrior
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Count().Should().Be(7);
result.Should().HaveCount(7);
}

[Fact]
Expand All @@ -280,6 +299,54 @@ public async Task GetNamedQueryResults_FilterByMultipleCriteria()
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Single().Id.Should().Be(AssetId.FromString("99/1/8"));
result.Should().ContainSingle(r => r.Id == AssetId.FromString("99/1/8"));
}

[Fact]
public async Task GetNamedQueryResults_FilterBySingleBatch()
{
// Arrange
var query = new ParsedNamedQuery(99)
{
Batches = new[] { 101010 }
};

// Act
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Should().HaveCount(3);
}

[Fact]
public async Task GetNamedQueryResults_FilterByMultipleBatch()
{
// Arrange
var query = new ParsedNamedQuery(99)
{
Batches = new[] { 101010, 101011 }
};

// Act
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Should().HaveCount(4);
}

[Fact]
public async Task GetNamedQueryResults_FilterByMultipleBatch_AndOtherCriteria()
{
// Arrange
var query = new ParsedNamedQuery(99)
{
Batches = new[] { 101010, 101011 }, Number3 = 1
};

// Act
var result = await sut.GetNamedQueryResults(query).ToListAsync();

// Assert
result.Should().HaveCount(3);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public void GenerateParsedNamedQueryFromRequest_ReturnsFaultParsedNQ_IfInvalidPa
[Theory]
[InlineData("n1=p1", "not-an-int")]
[InlineData("n1=p1&#=not-an-int", "")]
[InlineData("batch=p1", "not-an-int")]
[InlineData("batch=p1", "1|2|3")]
[InlineData("batch=p1&#=not-an-int", "")]
public void GenerateParsedNamedQueryFromRequest_ReturnsFaultParsedNQ_IfNonNumberPassedForNumberArg(
string template,
string args)
Expand Down Expand Up @@ -126,6 +129,12 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
"Space from template"
},
new object[]
{
"batch=p1&#=10", "",
new IIIFParsedNamedQuery(Customer) { Batches = new[] { 10 }, NamedQueryName = "my-query" },
"Single batch from template"
},
new object[]
{
"manifest=s1&spacename=p1", "10",
new IIIFParsedNamedQuery(Customer)
Expand All @@ -138,7 +147,7 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
new IIIFParsedNamedQuery(Customer)
{
String1 = "string-1", Number1 = 40, Space = 1, Manifest = ParsedNamedQuery.QueryMapping.String1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.Number2)},
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
NamedQueryName = "my-query"
},
"All params"
Expand All @@ -149,7 +158,7 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
new IIIFParsedNamedQuery(Customer)
{
String1 = "string-1", Number1 = 40, Space = 10, Manifest = ParsedNamedQuery.QueryMapping.String1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.Number2)},
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
NamedQueryName = "my-query"
},
"Extra args are ignored"
Expand All @@ -160,10 +169,21 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
new IIIFParsedNamedQuery(Customer)
{
String1 = "string-1", Number1 = 40, Space = 1, Manifest = ParsedNamedQuery.QueryMapping.String1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.Number2)},
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
NamedQueryName = "my-query"
},
"Incorrect template pairs are ignored"
},
new object[]
{
"manifest=s1&canvas=n2&s1=p1&n1=p2&batch=p3&space=p4&#=1", "string-1/40/10,20,30",
new IIIFParsedNamedQuery(Customer)
{
String1 = "string-1", Number1 = 40, Space = 1, Manifest = ParsedNamedQuery.QueryMapping.String1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
NamedQueryName = "my-query", Batches = new[] { 10, 20, 30 }
},
"All params including multi Batch"
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,21 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
"Spacename from param"
},
new object[]
{
"batch=p1", "10,20,40",
new PdfParsedNamedQuery(99)
{
NamedQueryName = "my-query", Batches = new[] { 10, 20, 40 }, Args = new List<string> { "10,20,40" }
},
"Batch from template"
},
new object[]
{
"redactedmessage=you cannot view&canvas=s1&s1=p1&n1=p2&space=p3&#=1", "string-1/40",
new PdfParsedNamedQuery(99)
{
String1 = "string-1", Number1 = 40, Space = 1, RedactedMessage = "you cannot view",
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.String1)},
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.String1) },
Args = new List<string> { "string-1", "40", "1" }, NamedQueryName = "my-query",
},
"All params except format"
Expand All @@ -174,7 +183,7 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
new PdfParsedNamedQuery(99)
{
String1 = "string-1", Number1 = 40, Space = 10,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.Number2)},
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
Args = new List<string> { "string-1", "40", "10", "100", "1" }, NamedQueryName = "my-query",
},
"Extra args are ignored"
Expand All @@ -184,8 +193,8 @@ public void GenerateParsedNamedQueryFromRequest_SuccessfullyParses(string templa
"manifest=s1&&n3=&canvas=n2&=10&s1=p1&n1=p2&space=p3&#=1", "string-1/40",
new PdfParsedNamedQuery(99)
{
String1 = "string-1", Number1 = 40, Space = 1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder>{new(ParsedNamedQuery.QueryMapping.Number2)},
String1 = "string-1", Number1 = 40, Space = 1,
AssetOrdering = new List<ParsedNamedQuery.QueryOrder> { new(ParsedNamedQuery.QueryMapping.Number2) },
Args = new List<string> { "string-1", "40", "1" }, NamedQueryName = "my-query",
},
"Incorrect template pairs are ignored"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using DLCS.Core.Caching;
using DLCS.Core.Collections;
using DLCS.Core.Strings;
using DLCS.Model.Assets;
using DLCS.Model.Assets.NamedQueries;
Expand Down Expand Up @@ -101,6 +102,11 @@ public IQueryable<Asset> GetNamedQueryResults(ParsedNamedQuery query)
.Select(arg => arg.Image);
}

if (!query.Batches.IsNullOrEmpty())
{
imageFilter = imageFilter.Where(i => i.BatchAssets.Any(ba => query.Batches.Contains(ba.BatchId)));
}

return imageFilter;
}
}
Loading

0 comments on commit 06c4236

Please sign in to comment.