Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions c-sharp-tests/DummyPapiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public override Task<bool> RegisterRequestHandlerAsync(
return Task.FromResult(_localMethods.TryAdd(requestType, requestHandler));
}

public IReadOnlyCollection<string> RegisteredRequestTypes => _localMethods.Keys.ToArray();

public override Task SendEventAsync(string eventType, object? eventParameters)
{
_sentEvents.Enqueue((eventType, eventParameters));
Expand Down
84 changes: 84 additions & 0 deletions c-sharp-tests/Projects/LocalParatextProjectsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,88 @@ string id
{
return new ProjectDetails(name, new ProjectMetadata(id, ["paratext"]), folder);
}

[Test]
public void GetParatextProjectInterfaces_Unpublished_IncludesLegacyComment()
{
var interfaces = LocalParatextProjects.GetParatextProjectInterfaces(isPublished: false);

Assert.That(interfaces, Does.Contain(ProjectInterfaces.LEGACY_COMMENT));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.BASE));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USFM_BOOK));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.SCRIPTURE_EDIT_PERMISSIONS));
}

[Test]
public void GetParatextProjectInterfaces_Published_ExcludesLegacyCommentButKeepsScripture()
{
var interfaces = LocalParatextProjects.GetParatextProjectInterfaces(isPublished: true);

Assert.That(interfaces, Does.Not.Contain(ProjectInterfaces.LEGACY_COMMENT));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.BASE));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USFM_BOOK));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USFM_CHAPTER));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USFM_VERSE));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USX_BOOK));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USX_CHAPTER));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.USX_VERSE));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.PLAIN_TEXT_VERSE));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.MARKER_NAMES));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.TEXT_CONNECTION_SETTINGS));
Assert.That(interfaces, Does.Contain(ProjectInterfaces.SCRIPTURE_EDIT_PERMISSIONS));
}

[TestCase("ABC_4488", "PRJX", "abc7")]
public void Initialize_SingleUnpublishedProject_AdvertisesUnpublishedInterfaces(
string folder,
string name,
string id
)
{
CreateTempProject(folder, CreateParatextProjectDetails(folder, name, id));
_localProjects.Initialize();

var details = _localProjects.GetProjectDetails(id);

// Unpublished projects must advertise the full interface list including legacyCommentManager.comments
Assert.That(
details.Metadata.ProjectInterfaces,
Does.Contain(ProjectInterfaces.LEGACY_COMMENT),
"Unpublished Paratext project must advertise legacyCommentManager.comments"
);
Assert.That(
details.Metadata.ProjectInterfaces,
Does.Contain(ProjectInterfaces.USFM_CHAPTER)
);
}

[Test]
public void GetAvailableUnpublishedProjectDetails_UnpublishedOnly_ReturnsAll()
{
CreateTempProject("NR1", CreateParatextProjectDetails("NR1", "First", "aaaa01"));
CreateTempProject("NR2", CreateParatextProjectDetails("NR2", "Second", "aaaa02"));
_localProjects.Initialize();

var unpublished = _localProjects.GetAvailableUnpublishedProjectDetails().ToList();

Assert.That(unpublished, Has.Count.EqualTo(2));
Assert.That(
unpublished.Select(d => d.Metadata.Id),
Is.EquivalentTo(new[] { "AAAA01", "AAAA02" })
);
}

[Test]
public void GetAvailablePublishedProjectDetails_NoPublished_ReturnsEmpty()
{
CreateTempProject("NR1", CreateParatextProjectDetails("NR1", "First", "aaaa01"));
_localProjects.Initialize();

var published = _localProjects.GetAvailablePublishedProjectDetails().ToList();

// DummyScrText / TestLocalParatextProjectsInTempDir produces unpublished ScrTexts
// (IsResourceProject defaults to false on the base ScrText class), so the published
// list is empty in this fixture. This documents the partition between the two helpers.
Assert.That(published, Is.Empty);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.Diagnostics.CodeAnalysis;
using Paranext.DataProvider.Projects;

namespace TestParanextDataProvider.Projects
{
[ExcludeFromCodeCoverage]
internal class ParatextProjectDataProviderWireSurfaceTests : PapiTestBase
{
private static readonly string[] AllCommentWireMethodSuffixes =
[
".getCommentThreads",
".createComment",
".addCommentToThread",
".deleteComment",
".updateComment",
".setIsCommentThreadRead",
".findAssignableUsers",
".canUserCreateComments",
".canUserAddCommentToThread",
".canUserAssignThread",
".canUserResolveThread",
".canUserEditOrDeleteComment",
];

[Test]
public async Task UnpublishedPdp_RegistersAllCommentMethodsAsync()
{
// Arrange: unpublished project advertises the full interface list including
// legacyCommentManager.comments
const string projId = "117777";
var details = CreateProjectDetails(
projId,
"RegProj",
LocalParatextProjects.GetParatextProjectInterfaces(isPublished: false)
);
ParatextProjects.FakeAddProject(details);

// Act: construct PPDP and register it on the wire
var pdp = new ParatextProjectDataProvider("PdpA", Client, details, ParatextProjects);
await pdp.RegisterDataProviderAsync();

// Assert: every comment method is on the wire
foreach (var suffix in AllCommentWireMethodSuffixes)
{
Assert.That(
Client.RegisteredRequestTypes.Any(k => k.EndsWith(suffix)),
Is.True,
$"Expected unpublished PDP to register a wire method ending in '{suffix}'"
);
}
}

[Test]
public async Task PublishedPdp_DoesNotRegisterAnyCommentMethodAsync()
{
// Arrange: published project advertises only the published interface list (no
// legacyCommentManager.comments)
const string projId = "227777";
var details = CreateProjectDetails(
projId,
"PublishedProj",
LocalParatextProjects.GetParatextProjectInterfaces(isPublished: true)
);
ParatextProjects.FakeAddProject(details);

// Act: construct PPDP and register it on the wire
var pdp = new ParatextProjectDataProvider("PdpB", Client, details, ParatextProjects);
await pdp.RegisterDataProviderAsync();

// Assert: no comment method appears on the wire
foreach (var suffix in AllCommentWireMethodSuffixes)
{
Assert.That(
Client.RegisteredRequestTypes.Any(k => k.EndsWith(suffix)),
Is.False,
$"Published PDP must NOT register a wire method ending in '{suffix}'"
);
}

// Sanity: scripture methods ARE registered (the published project is still readable)
Assert.That(
Client.RegisteredRequestTypes.Any(k => k.EndsWith(".getChapterUSFM")),
Is.True,
"Published PDP must still register scripture read methods"
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Diagnostics.CodeAnalysis;
using Paranext.DataProvider.Projects;

namespace TestParanextDataProvider.Projects
{
[ExcludeFromCodeCoverage]
internal class ParatextPublishedProjectDataProviderFactoryTests : PapiTestBase
{
[SetUp]
public override async Task TestSetupAsync()
{
await base.TestSetupAsync();
}

[Test]
public async Task PublishedFactory_AdvertisesInterfaceListWithoutLegacyCommentAsync()
{
var factory = new ParatextPublishedProjectDataProviderFactory(Client, ParatextProjects);
await factory.InitializeAsync();

// Truth check on the source of advertised interfaces.
var advertised = LocalParatextProjects.GetParatextProjectInterfaces(isPublished: true);

Assert.That(advertised, Does.Not.Contain(ProjectInterfaces.LEGACY_COMMENT));
Assert.That(advertised, Does.Contain(ProjectInterfaces.USFM_CHAPTER));
Assert.That(advertised, Does.Contain(ProjectInterfaces.BASE));
}

[Test]
public async Task PublishedFactory_GetAvailableProjects_IsEmptyForDummyUnpublishedFixturesAsync()
{
// DummyScrText / FakeAddProject produces unpublished ScrTexts (IsResourceProject ==
// false on the base ScrText class), so the published factory's available list is empty
// in the unit-test fixture. This is the partition assertion: unpublished projects go
// to the other factory, not this one.
const string projId = "315555";
ParatextProjects.FakeAddProject(CreateProjectDetails(projId, "RegProj"));

var factory = new ParatextPublishedProjectDataProviderFactory(Client, ParatextProjects);
await factory.InitializeAsync();

Assert.Throws<KeyNotFoundException>(() => factory.GetProjectDataProviderID(projId));
}
}
}
5 changes: 5 additions & 0 deletions c-sharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ public static async Task Main()

SettingsService.Initialize(papi);
var paratextFactory = new ParatextProjectDataProviderFactory(papi, paratextProjects);
var paratextPublishedFactory = new ParatextPublishedProjectDataProviderFactory(
papi,
paratextProjects
);
var paratextSendReceiveService = new ParatextProjectSendReceiveService(
papi,
paratextFactory,
Expand All @@ -80,6 +84,7 @@ public static async Task Main()
var paratextRegistrationService = new ParatextRegistrationService(papi);
await Task.WhenAll(
paratextFactory.InitializeAsync(),
paratextPublishedFactory.InitializeAsync(),
inventoryDataProvider.RegisterDataProviderAsync(),
checkRunner.RegisterDataProviderAsync(),
dblResources.RegisterDataProviderAsync(),
Expand Down
Loading
Loading