Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e52e2d1
Make root network applicabilities explicit
flomillot Oct 10, 2026
87de498
Merge remote-tracking branch 'origin/main' into refactor/explicit-roo…
flomillot Oct 15, 2026
44f111d
Give the modifications an applicability for the tag of a new root net…
flomillot Oct 16, 2026
b25b25d
Set the default applicabilities of the shared modifications in Java
flomillot Oct 21, 2026
6ba2413
Merge remote-tracking branch 'origin/main' into HEAD
flomillot Oct 21, 2026
c8bc6a5
Merge remote-tracking branch 'origin/main' into HEAD
flomillot Oct 21, 2026
91d7213
Pass the root network tags in the tests coming from main
flomillot Oct 21, 2026
f118575
Merge remote-tracking branch 'origin/refactor/explicit-root-network-a…
flomillot Oct 21, 2026
bf9f82e
Add the root network tag applicabilities in Java
flomillot Oct 21, 2026
4dee0f2
Remove comments restating the code
flomillot Oct 22, 2026
f96feb5
Merge remote-tracking branch 'origin/refactor/explicit-root-network-a…
flomillot Oct 22, 2026
b4bb64f
Remove a comment restating the test
flomillot Oct 22, 2026
cff114f
Merge remote-tracking branch 'origin/main' into HEAD
flomillot Oct 23, 2026
6e8b308
Merge remote-tracking branch 'origin/main' into feat/new-root-network…
flomillot Oct 23, 2026
f4fea8d
Remove the test duplicated by the merge of main
flomillot Oct 23, 2026
f87f9d5
Merge remote-tracking branch 'origin/main' into HEAD
flomillot Oct 26, 2026
fa5f177
Merge remote-tracking branch 'origin/main' into HEAD
flomillot Oct 26, 2026
cd18db3
Merge branch 'main' into feat/new-root-network-applicability
etiennehomer Oct 27, 2026
6b94910
"Remove redundant comment in NetworkModificationRepository"
flomillot Oct 27, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,16 @@ public ResponseEntity<Void> updateRootNetworkApplicability(
return ResponseEntity.ok().build();
}

@PostMapping(value = "/network-modifications/root-network-tag")
@Operation(summary = "Adds a root network tag to the applicabilities of the modifications of the given groups, if not present")
@ApiResponse(responseCode = "200", description = "The root network tag has been successfully added")
public ResponseEntity<Void> addRootNetworkTag(
@Parameter(description = "Modification groups UUIDs") @RequestParam("groupUuids") List<UUID> groupUuids,
@Parameter(description = "Root network tag to add") @RequestParam("newTag") String newTag) {
networkModificationService.addRootNetworkTag(groupUuids, newTag);
return ResponseEntity.ok().build();
}

@PutMapping(value = "/network-modifications/root-network-tag")
@Operation(summary = "Renames a root network tag in the applicabilities of the modifications of the given groups")
@ApiResponse(responseCode = "200", description = "The root network tag has been successfully renamed")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ public void setDefaultApplicabilityIfMissing(String rootNetworkTag) {
}
}

public void addApplicabilityIfMissing(String rootNetworkTag) {
if (findApplicability(rootNetworkTag).isEmpty()) {
boolean applicable = applicabilities.stream().noneMatch(applicability -> Boolean.FALSE.equals(applicability.getApplicable()));
applicabilities.add(new ModificationRootNetworkApplicabilityEntity(this, rootNetworkTag, applicable));
}
}

public Set<String> getRootNetworkTags() {
return applicabilities.stream().map(ModificationRootNetworkApplicabilityEntity::getRootNetworkTag).collect(Collectors.toSet());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,23 @@ private List<ModificationEntity> getApplicabilityHolders(List<ModificationEntity
.toList();
}

/**
* Gives an applicability for {@code newTag} to the modifications of the given groups and to the shared ones they
* point to, unless they already have one for it: they are applicable on it unless they are not applicable on
* another tag, of the study or not.
*/
@Transactional
public void addRootNetworkTag(@NonNull List<UUID> groupUuids, @NonNull String newTag) {
List<UUID> ownedUuids = getContainedModificationUuidsNonTransactional(groupUuids);
if (ownedUuids.isEmpty()) {
return;
}
Set<UUID> sharedModificationTreesUuids = getSharedModificationTrees(ownedUuids).allUuids();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these first lines are the same as in renameRootNetworkTag
=> create small private function to avoid fixing this in two places lates

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you suggest something because I don't see how to make it without adding more code ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can create record hold both result of what you called ownedUuids and sharedTreesUuids ...
never mind it can be done next time

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but it add more codes, create a record used only once, and don't make it clearer IMO, unless I haven't understand

modificationRepository.findAllWithApplicabilitiesByIdIn(SetUtils.union(Set.copyOf(ownedUuids), sharedModificationTreesUuids)).stream()
.filter(Predicate.not(ModificationReferenceEntity.class::isInstance))
.forEach(modification -> modification.addApplicabilityIfMissing(newTag));
}

/**
* Moves the applicability entries of {@code oldTag} to {@code newTag}, after dropping the entries of {@code newTag}:
* <ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,12 @@ public void updateRootNetworkApplicability(@NonNull List<UUID> modificationUuids
emitReferencedAncestorsUpdated(modificationUuids, userId);
}

@Transactional
public void addRootNetworkTag(@NonNull List<UUID> groupUuids, @NonNull String newTag) {
assertRootNetworkTagFits(newTag);
networkModificationRepository.addRootNetworkTag(groupUuids, newTag);
}

/**
* Renames the root network tag of the modifications of the given groups. The shared modifications the user cannot
* write on are left out of the renaming: their applicabilities, and the ones of their content, are left untouched.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class ModificationControllerTest {

private static final String ROOT_NETWORK_TAG = "PH1";
private static final String RENAMED_ROOT_NETWORK_TAG = "PH2";
private static final String NEW_ROOT_NETWORK_TAG = "PH3";

private static final String URI_NETWORK_MODIF_BASE = "/v1/network-modifications";
private static final String NETWORK_MODIFICATION_URI = URI_NETWORK_MODIF_BASE + "?groupUuid=" + TEST_GROUP_ID;
Expand Down Expand Up @@ -558,7 +559,7 @@ private Map<UUID, Map<String, Boolean>> readApplicabilities(UUID groupUuid) thro
}

@Test
void testRenameAndDeleteRootNetworkTag() throws Exception {
void testAddRenameAndDeleteRootNetworkTag() throws Exception {
List<ModificationInfos> modifications = createSomeSwitchModifications(TEST_GROUP_ID, 1);
UUID modificationUuid = modifications.getFirst().getUuid();
mockMvc.perform(put(URI_NETWORK_MODIF_BASE + "/root-network-applicability")
Expand All @@ -568,21 +569,27 @@ void testRenameAndDeleteRootNetworkTag() throws Exception {
.queryParam("applicable", "false")
).andExpect(status().isOk());

mockMvc.perform(post(URI_NETWORK_MODIF_BASE + "/root-network-tag")
.queryParam("groupUuids", TEST_GROUP_ID.toString())
.queryParam("newTag", NEW_ROOT_NETWORK_TAG)
).andExpect(status().isOk());
assertEquals(Map.of(ROOT_NETWORK_TAG, false, NEW_ROOT_NETWORK_TAG, false), readApplicabilities(TEST_GROUP_ID).get(modificationUuid));

// renaming the root network tag carries along its applicabilities
mockMvc.perform(put(URI_NETWORK_MODIF_BASE + "/root-network-tag")
.queryParam("groupUuids", TEST_GROUP_ID.toString())
.queryParam("oldTag", ROOT_NETWORK_TAG)
.queryParam("newTag", RENAMED_ROOT_NETWORK_TAG)
.header(HEADER_USER_ID, TEST_USER_ID)
).andExpect(status().isOk());
assertEquals(Map.of(RENAMED_ROOT_NETWORK_TAG, false), readApplicabilities(TEST_GROUP_ID).get(modificationUuid));
assertEquals(Map.of(RENAMED_ROOT_NETWORK_TAG, false, NEW_ROOT_NETWORK_TAG, false), readApplicabilities(TEST_GROUP_ID).get(modificationUuid));

// and dropping the tag takes its applicabilities away
mockMvc.perform(delete(URI_NETWORK_MODIF_BASE + "/root-network-tag")
.queryParam("groupUuids", TEST_GROUP_ID.toString())
.queryParam("rootNetworkTags", RENAMED_ROOT_NETWORK_TAG)
).andExpect(status().isOk());
assertEquals(Map.of(), readApplicabilities(TEST_GROUP_ID).get(modificationUuid));
assertEquals(Map.of(NEW_ROOT_NETWORK_TAG, false), readApplicabilities(TEST_GROUP_ID).get(modificationUuid));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,40 @@ void testCommonRootNetworkTags() {
assertEquals(List.of(), networkModificationRepository.getCommonRootNetworkTags(Set.of(bothTagsUuid, noTagUuid)));
}

@Test
void testAddRootNetworkTagFollowsTheApplicabilitiesOfTheGroupModifications() {
List<ModificationInfos> modifications = networkModificationRepository.saveModifications(TEST_GROUP_ID_3,
List.of(switchModification("v1d1"), switchModification("v1d2"), switchModification("v1d3"), switchModification("v1d4")));
UUID activatedUuid = modifications.get(0).getUuid();
UUID deactivatedUuid = modifications.get(1).getUuid();
UUID memorizedUuid = modifications.get(2).getUuid();
UUID withoutApplicabilityUuid = modifications.get(3).getUuid();
UUID compositeUuid = insertComposite(TEST_GROUP_ID_3, false, "v1d5");
UUID referenceUuid = insertComposite(TEST_GROUP_ID_3, true, "v1d6");
networkModificationRepository.updateRootNetworkApplicability(List.of(activatedUuid, deactivatedUuid, memorizedUuid, compositeUuid), "A", true);
networkModificationRepository.updateRootNetworkApplicability(List.of(activatedUuid), "B", true);
networkModificationRepository.updateRootNetworkApplicability(List.of(deactivatedUuid, compositeUuid), "B", false);
// memorized by a copy from another study, whose root network had this tag
networkModificationRepository.updateRootNetworkApplicability(List.of(memorizedUuid), "D", false);

networkModificationRepository.addRootNetworkTag(List.of(TEST_GROUP_ID_3), "D");

Map<UUID, Map<String, Boolean>> applicabilities = getApplicabilities(TEST_GROUP_ID_3);
assertEquals(Map.of("A", true, "B", true, "D", true), applicabilities.get(activatedUuid),
"A modification applicable on all its root networks is applicable on the new one");
assertEquals(Map.of("A", true, "B", false, "D", false), applicabilities.get(deactivatedUuid),
"A modification not applicable on one of its root networks is not applicable on the new one");
assertEquals(Map.of("A", true, "D", false), applicabilities.get(memorizedUuid),
"The applicability already memorized for the new tag is kept");
assertEquals(Map.of("D", true), applicabilities.get(withoutApplicabilityUuid),
"A modification without applicability is applicable on the new root network");
assertEquals(List.of(Map.of("D", true)), List.copyOf(getApplicabilitiesByModificationsInside(compositeUuid).values()),
"The content of a composite is reached, and follows its own applicabilities");
assertEquals(Map.of("D", true), applicabilities.get(referenceUuid), "The shared modification a reference points to is reached");
assertEquals(List.of(Map.of("D", true)), List.copyOf(getApplicabilitiesByModificationsInside(sharedModificationOf(referenceUuid)).values()),
"So is its content");
}

@Test
void testRenameRootNetworkTagMovesTheApplicabilityOfTheGroupModifications() {
List<ModificationInfos> modifications = networkModificationRepository.saveModifications(TEST_GROUP_ID_3,
Expand Down
Loading