Skip to content

Commit c1628df

Browse files
committed
- Refactor ModifiablePublisherRole and ModifiableUserRole to support additional image parameters
- Added overloads for AddImageAsync methods in ModifiablePublisherRole and ModifiableUserRole to accept optional id and name parameters. - Updated RemoveImageAsync methods to accept imageId instead of imageFile. - Adjusted event IDs in ModifiablePublisherRoleCollection and ModifiableUserRoleCollection for consistency. - Renamed InnerPublisherRoles to InnerPublisherRoleCollection in ModifiableUser for clarity. - Introduced NameIdOverriddenGetCidFile class to handle files with overridden IDs and names. - Updated ReadOnlyImagesCollection to utilize the new NameIdOverriddenGetCidFile for image handling. - Modified RepositoryContainer to accept additional managed configurations for users, projects, and publishers. - Updated tests across BasicTests, ProjectTests, PublisherTests, and UserTests to reflect changes in repository container initialization and key management.
1 parent 2887799 commit c1628df

23 files changed

+312
-217
lines changed

src/IModifiableImagesCollection.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,22 @@ public interface IModifiableImagesCollection : IReadOnlyImagesCollection
1414
/// <param name="cancellationToken">A token that can be used to cancel the ongoing operation.</param>
1515
Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken);
1616

17+
/// <summary>
18+
/// Adds an image to the collection with a specified ID and name.
19+
/// </summary>
20+
/// <remarks>
21+
/// If the ID is not provided, the image's own ID will be used. If the name is not provided, the image's own name will be used.
22+
/// </remarks>
23+
/// <param name="imageFile">The image file to add to the collection.</param>
24+
/// <param name="id">An optional ID to assign to the image.</param>
25+
/// <param name="name">An optional name to assign to the image.</param>
26+
/// <param name="cancellationToken">A token that can be used to cancel the ongoing operation.</param>
27+
Task AddImageAsync(IFile imageFile, string? id, string? name, CancellationToken cancellationToken);
28+
1729
/// <summary>
1830
/// Removes an image from the collection.
1931
/// </summary>
20-
/// <param name="imageFile">The image file to remove from the collection.</param>
32+
/// <param name="imageId">The ID of the image file to remove from the collection.</param>
2133
/// <param name="cancellationToken">A token that can be used to cancel the ongoing operation.</param>
22-
Task RemoveImageAsync(IFile imageFile, CancellationToken cancellationToken);
34+
Task RemoveImageAsync(string imageId, CancellationToken cancellationToken);
2335
}

src/Nomad/IdOverriddenIpfsFile.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Nomad/ModifiableEntity.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class ModifiableEntity : NomadKuboEventStreamHandler<ValueUpdateEvent>, I
3131
/// <summary>
3232
/// The links associated with this entity.
3333
/// </summary>
34-
public required IModifiableLinksCollection InnerLinks { get; init; }
34+
public required ModifiableLinksCollection InnerLinks { get; init; }
3535

3636
/// <inheritdoc />
3737
public string Name => Inner.Inner.Name;
@@ -100,7 +100,10 @@ public class ModifiableEntity : NomadKuboEventStreamHandler<ValueUpdateEvent>, I
100100
public Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerImages.AddImageAsync(imageFile, cancellationToken);
101101

102102
/// <inheritdoc />
103-
public Task RemoveImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerImages.RemoveImageAsync(imageFile, cancellationToken);
103+
public Task AddImageAsync(IFile imageFile, string? id, string? name, CancellationToken cancellationToken) => InnerImages.AddImageAsync(imageFile, id, name, cancellationToken);
104+
105+
/// <inheritdoc />
106+
public Task RemoveImageAsync(string imageId, CancellationToken cancellationToken) => InnerImages.RemoveImageAsync(imageId, cancellationToken);
104107

105108
/// <inheritdoc />
106109
public Task AddLinkAsync(Link link, CancellationToken cancellationToken) => InnerLinks.AddLinkAsync(link, cancellationToken);
@@ -127,26 +130,22 @@ public override async Task ApplyEntryUpdateAsync(EventStreamEntry<DagCid> eventS
127130
}
128131
case nameof(AddConnectionAsync):
129132
{
130-
// TODO: Needs implementation, not interface
131-
// await InnerConnections.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
133+
await InnerConnections.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
132134
break;
133135
}
134136
case nameof(RemoveConnectionAsync):
135137
{
136-
// TODO: Needs implementation, not interface
137-
// await InnerConnections.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
138+
await InnerConnections.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
138139
break;
139140
}
140141
case nameof(AddLinkAsync):
141142
{
142-
// TODO: Needs implementation, not interface
143-
// await InnerLinks.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
143+
await InnerLinks.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
144144
break;
145145
}
146146
case nameof(RemoveLinkAsync):
147147
{
148-
// TODO: Needs implementation, not interface
149-
// await InnerLinks.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
148+
await InnerLinks.ApplyEntryUpdateAsync(eventStreamEntry, updateEvent, cancellationToken);
150149
break;
151150
}
152151
case nameof(UpdateNameAsync):

src/Nomad/ModifiableImagesCollection.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,26 @@ public class ModifiableImagesCollection : NomadKuboEventStreamHandler<ValueUpdat
2525
public required string Id { get; init; }
2626

2727
/// <inheritdoc />
28-
public async Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken)
28+
public Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken)
2929
{
30-
var imageCid = await imageFile.GetCidAsync(Inner.Client, new AddFileOptions { Pin = KuboOptions.ShouldPin, }, cancellationToken);
30+
cancellationToken.ThrowIfCancellationRequested();
31+
return AddImageAsync(imageFile, id: null, name: null, cancellationToken);
32+
}
33+
34+
/// <inheritdoc />
35+
public async Task AddImageAsync(IFile imageFile, string? id, string? name, CancellationToken cancellationToken)
36+
{
37+
var imageCid = await imageFile.GetCidAsync(Inner.Client, new AddFileOptions { Pin = KuboOptions.ShouldPin }, cancellationToken);
3138

3239
var newImage = new Image
3340
{
34-
Id = imageFile.Id,
35-
Name = imageFile.Name,
41+
Id = id ?? imageFile.Id,
42+
Name = name ?? imageFile.Name,
3643
Cid = (DagCid)imageCid,
3744
};
3845

3946
var keyCid = await Client.Dag.PutAsync(newImage.Id, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
4047
var valueCid = await Client.Dag.PutAsync(newImage, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
41-
4248
var updateEvent = new ValueUpdateEvent((DagCid)keyCid, (DagCid)valueCid, false);
4349

4450
var appendedEntry = await AppendNewEntryAsync(targetId: Id, eventId: nameof(AddImageAsync), updateEvent, DateTime.UtcNow, cancellationToken);
@@ -48,21 +54,20 @@ public async Task AddImageAsync(IFile imageFile, CancellationToken cancellationT
4854
}
4955

5056
/// <inheritdoc />
51-
public async Task RemoveImageAsync(IFile imageFile, CancellationToken cancellationToken)
57+
public async Task RemoveImageAsync(string imageId, CancellationToken cancellationToken)
5258
{
53-
var image = Inner.Inner.Images.FirstOrDefault(img => img.Id == imageFile.Id);
59+
var image = Inner.Inner.Images.FirstOrDefault(img => img.Id == imageId);
5460
if (image == null)
5561
{
56-
throw new ArgumentException("Image not found in the collection.", nameof(imageFile));
62+
throw new ArgumentException($"Image with ID {imageId} not found in the collection.", nameof(imageId));
5763
}
5864

5965
var keyCid = await Client.Dag.PutAsync(image.Id, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
6066
var valueCid = await Client.Dag.PutAsync(image, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
61-
6267
var updateEvent = new ValueUpdateEvent((DagCid)keyCid, (DagCid)valueCid, true);
6368

6469
var appendedEntry = await AppendNewEntryAsync(Id, nameof(RemoveImageAsync), updateEvent, DateTime.UtcNow, cancellationToken);
65-
await ApplyEntryUpdateAsync(appendedEntry, updateEvent, image, imageFile, cancellationToken);
70+
await ApplyEntryUpdateAsync(appendedEntry, updateEvent, image, null, cancellationToken);
6671

6772
EventStreamPosition = appendedEntry;
6873
}
@@ -82,7 +87,7 @@ public async Task RemoveImageAsync(IFile imageFile, CancellationToken cancellati
8287
/// <remarks>
8388
/// This method will call <see cref="ReadOnlyImagesCollection.GetAsync(string, CancellationToken)"/> and create a new instance to pass to the event handlers.
8489
/// <para/>
85-
/// If already have a resolved instance of <see cref="Image"/>, you should call <see cref="ApplyEntryUpdateAsync(EventStreamEntry{DagCid}, ValueUpdateEvent, Image, CancellationToken)"/> instead.
90+
/// If already have a resolved instance of <see cref="Image"/>, you should call <see cref="ApplyEntryUpdateAsync(EventStreamEntry{DagCid}, ValueUpdateEvent, Image, IFile?, CancellationToken)"/> instead.
8691
/// </remarks>
8792
/// <param name="eventStreamEntry">The event stream entry to apply.</param>
8893
/// <param name="updateEvent">The update event to apply.</param>
@@ -116,15 +121,15 @@ public async Task ApplyEntryUpdateAsync(EventStreamEntry<DagCid> eventStreamEntr
116121
{
117122
case nameof(AddImageAsync):
118123
{
124+
var imageFile = file ??= Inner.ImageToFile(image);
119125
Inner.Inner.Images = [.. Inner.Inner.Images, image];
120-
var imageFile = file ??= await Inner.GetAsync(image.Id, cancellationToken);
121126
ImagesAdded?.Invoke(this, [imageFile]);
122127
break;
123128
}
124129
case nameof(RemoveImageAsync):
125130
{
131+
var imageFile = file ??= Inner.ImageToFile(image);
126132
Inner.Inner.Images = [.. Inner.Inner.Images.Except([image])];
127-
var imageFile = file ??= await Inner.GetAsync(image.Id, cancellationToken);
128133
ImagesRemoved?.Invoke(this, [imageFile]);
129134
break;
130135
}

src/Nomad/ModifiableLinksCollection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,14 @@ public async Task ApplyEntryUpdateAsync(EventStreamEntry<DagCid> eventStreamEntr
113113
case nameof(AddLinkAsync):
114114
{
115115
Inner.Inner.Links = [.. Inner.Inner.Links, linkModel];
116-
linkAppModel ??= await Inner.GetAsync(linkModel.Id, cancellationToken);
116+
linkAppModel ??= new Link { Description = linkModel.Description, Id = linkModel.Id, Name = linkModel.Name, Url = linkModel.Url, };
117117
LinksAdded?.Invoke(this, [linkAppModel]);
118118
break;
119119
}
120120
case nameof(RemoveLinkAsync):
121121
{
122122
Inner.Inner.Links = [.. Inner.Inner.Links.Except([linkModel])];
123-
linkAppModel ??= await Inner.GetAsync(linkModel.Id, cancellationToken);
123+
linkAppModel ??= new Link { Description = linkModel.Description, Id = linkModel.Id, Name = linkModel.Name, Url = linkModel.Url, };
124124
LinksRemoved?.Invoke(this, [linkAppModel]);
125125
break;
126126
}

src/Nomad/ModifiableProject.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
4747
EventStreamHandlerId = handlerConfig.RoamingKey.Id,
4848
LocalEventStream = handlerConfig.LocalValue,
4949
LocalEventStreamKey = handlerConfig.LocalKey,
50-
Sources = handlerConfig.RoamingValue.Sources,
50+
Sources = handlerConfig.Sources,
5151
KuboOptions = kuboOptions,
5252
Client = client,
5353
};
@@ -59,7 +59,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
5959
EventStreamHandlerId = handlerConfig.RoamingKey.Id,
6060
LocalEventStream = handlerConfig.LocalValue,
6161
LocalEventStreamKey = handlerConfig.LocalKey,
62-
Sources = handlerConfig.RoamingValue.Sources,
62+
Sources = handlerConfig.Sources,
6363
KuboOptions = kuboOptions,
6464
Client = client,
6565
};
@@ -72,7 +72,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
7272
EventStreamHandlerId = handlerConfig.RoamingKey.Id,
7373
LocalEventStream = handlerConfig.LocalValue,
7474
LocalEventStreamKey = handlerConfig.LocalKey,
75-
Sources = handlerConfig.RoamingValue.Sources,
75+
Sources = handlerConfig.Sources,
7676
KuboOptions = kuboOptions,
7777
Client = client,
7878
};
@@ -88,7 +88,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
8888
InnerConnections = modifiableConnectionsCollection,
8989
InnerImages = modifiableImagesCollection,
9090
InnerLinks = modifiableLinksCollection,
91-
Sources = handlerConfig.RoamingValue.Sources,
91+
Sources = handlerConfig.Sources,
9292
KuboOptions = kuboOptions,
9393
Client = client,
9494
};
@@ -103,7 +103,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
103103
LocalEventStreamKey = handlerConfig.LocalKey,
104104
LocalEventStream = handlerConfig.LocalValue,
105105
KuboOptions = kuboOptions,
106-
Sources = handlerConfig.RoamingValue.Sources,
106+
Sources = handlerConfig.Sources,
107107
};
108108

109109
ModifiableUserRoleCollection modifiableUserRoleCollection = new()
@@ -116,7 +116,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
116116
LocalEventStreamKey = handlerConfig.LocalKey,
117117
LocalEventStream = handlerConfig.LocalValue,
118118
KuboOptions = kuboOptions,
119-
Sources = handlerConfig.RoamingValue.Sources,
119+
Sources = handlerConfig.Sources,
120120
UserRepository = userRepository,
121121
};
122122

@@ -131,7 +131,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
131131
LocalEventStream = handlerConfig.LocalValue,
132132
KuboOptions = kuboOptions,
133133
ProjectRepository = projectDependencyRepository,
134-
Sources = handlerConfig.RoamingValue.Sources,
134+
Sources = handlerConfig.Sources,
135135
};
136136

137137
// Modifiable project root event stream handler.
@@ -146,7 +146,7 @@ public static ModifiableProject FromHandlerConfig(NomadKuboEventStreamHandlerCon
146146
Dependencies = dependencies,
147147
PublisherRepository = publisherRepository,
148148
RoamingKey = handlerConfig.RoamingKey,
149-
Sources = handlerConfig.RoamingValue.Sources,
149+
Sources = handlerConfig.Sources,
150150
LocalEventStreamKey = handlerConfig.LocalKey,
151151
LocalEventStream = handlerConfig.LocalValue,
152152
KuboOptions = kuboOptions,
@@ -358,7 +358,10 @@ public async Task RemoveFeatureAsync(string feature, CancellationToken cancellat
358358
public Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerEntity.AddImageAsync(imageFile, cancellationToken);
359359

360360
/// <inheritdoc/>
361-
public Task RemoveImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerEntity.RemoveImageAsync(imageFile, cancellationToken);
361+
public Task AddImageAsync(IFile imageFile, string? id, string? name, CancellationToken cancellationToken) => InnerEntity.AddImageAsync(imageFile, id, name, cancellationToken);
362+
363+
/// <inheritdoc/>
364+
public Task RemoveImageAsync(string imageId, CancellationToken cancellationToken) => InnerEntity.RemoveImageAsync(imageId, cancellationToken);
362365

363366
/// <inheritdoc/>
364367
public Task UpdateAccentColorAsync(string? accentColor, CancellationToken cancellationToken) => InnerAccentColor.UpdateAccentColorAsync(accentColor, cancellationToken);
@@ -419,6 +422,12 @@ public override async Task ApplyEntryUpdateAsync(EventStreamEntry<DagCid> stream
419422
case nameof(UpdateAccentColorAsync):
420423
await InnerAccentColor.ApplyEntryUpdateAsync(streamEntry, updateEvent, cancellationToken);
421424
break;
425+
case "AddUserRoleAsync":
426+
await InnerUserRoleCollection.ApplyEntryUpdateAsync(streamEntry, updateEvent, cancellationToken);
427+
break;
428+
case "RemoveUserRoleAsync":
429+
await InnerUserRoleCollection.ApplyEntryUpdateAsync(streamEntry, updateEvent, cancellationToken);
430+
break;
422431
case nameof(UpdatePublisherAsync):
423432
Guard.IsNotNull(updateEvent.Value);
424433
var publisherId = await Client.Dag.GetAsync<Cid>(updateEvent.Value, cancel: cancellationToken);

src/Nomad/ModifiableProjectCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace WindowsAppCommunity.Sdk.Nomad;
1111
/// <summary>
1212
/// A modifiable handler for roaming project collection data.
1313
/// </summary>
14-
public class ModifiableProjectCollection : NomadKuboEventStreamHandler<ValueUpdateEvent>, IModifiableProjectCollection<IReadOnlyProject>
14+
public class ModifiableProjectCollection : NomadKuboEventStreamHandler<ValueUpdateEvent>, IModifiableProjectCollection<IReadOnlyProject>, IReadOnlyProjectCollection
1515
{
1616
/// <inheritdoc/>
1717
public required string Id { get; init; }

src/Nomad/ModifiableProjectRole.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public class ModifiableProjectRole : IModifiableProjectRole
111111
/// <inheritdoc/>
112112
public Task AddImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerProject.AddImageAsync(imageFile, cancellationToken);
113113

114+
/// <inheritdoc/>
115+
public Task AddImageAsync(IFile imageFile, string? id, string? name, CancellationToken cancellationToken) => InnerProject.AddImageAsync(imageFile, id, name, cancellationToken);
116+
114117
/// <inheritdoc/>
115118
public Task AddLinkAsync(Link link, CancellationToken cancellationToken) => InnerProject.AddLinkAsync(link, cancellationToken);
116119

@@ -136,7 +139,7 @@ public class ModifiableProjectRole : IModifiableProjectRole
136139
public Task RemoveFeatureAsync(string feature, CancellationToken cancellationToken) => InnerProject.RemoveFeatureAsync(feature, cancellationToken);
137140

138141
/// <inheritdoc/>
139-
public Task RemoveImageAsync(IFile imageFile, CancellationToken cancellationToken) => InnerProject.RemoveImageAsync(imageFile, cancellationToken);
142+
public Task RemoveImageAsync(string imageId, CancellationToken cancellationToken) => InnerProject.RemoveImageAsync(imageId, cancellationToken);
140143

141144
/// <inheritdoc/>
142145
public Task RemoveLinkAsync(Link link, CancellationToken cancellationToken) => InnerProject.RemoveLinkAsync(link, cancellationToken);

0 commit comments

Comments
 (0)