Skip to content

Commit 25a03f8

Browse files
authored
[WordService] Refactor RestoreFrontierWords (#4161)
1 parent 69321ea commit 25a03f8

4 files changed

Lines changed: 51 additions & 17 deletions

File tree

Backend.Tests/Mocks/WordRepositoryMock.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,20 @@ public Task<List<Word>> GetAllWords(string projectId)
3535
{
3636
try
3737
{
38-
var foundWord = _words.Single(word => word.Id == wordId);
39-
return Task.FromResult<Word?>(foundWord.Clone());
38+
return Task.FromResult<Word?>(_words.Single(w => w.ProjectId == projectId && w.Id == wordId).Clone());
4039
}
4140
catch (InvalidOperationException)
4241
{
4342
return Task.FromResult<Word?>(null);
4443
}
4544
}
4645

46+
public Task<List<Word>> GetWords(string projectId, List<string> wordIds)
47+
{
48+
return Task.FromResult(
49+
_words.Where(w => w.ProjectId == projectId && wordIds.Contains(w.Id)).Select(w => w.Clone()).ToList());
50+
}
51+
4752
public Task<Word> Create(Word word)
4853
{
4954
word.Id = Guid.NewGuid().ToString();

Backend/Interfaces/IWordRepository.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public interface IWordRepository
88
{
99
Task<List<Word>> GetAllWords(string projectId);
1010
Task<Word?> GetWord(string projectId, string wordId);
11+
Task<List<Word>> GetWords(string projectId, List<string> wordIds);
1112
Task<Word> Create(Word word);
1213
Task<List<Word>> Create(List<Word> words);
1314
Task<Word> Add(Word word);

Backend/Repositories/WordRepository.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,17 @@ public async Task<List<Word>> GetAllWords(string projectId)
8080
}
8181
}
8282

83-
/// <summary> Removes all <see cref="Word"/>s from the WordsCollection and Frontier for specified
84-
/// <see cref="Project"/> </summary>
83+
/// <summary> Finds project <see cref="Word"/>s with specified ids </summary>
84+
public async Task<List<Word>> GetWords(string projectId, List<string> wordIds)
85+
{
86+
using var activity = OtelService.StartActivityWithTag(otelTagName, "getting words");
87+
88+
return await _words.Find(GetProjectWordsFilter(projectId, wordIds)).ToListAsync();
89+
}
90+
91+
/// <summary>
92+
/// Removes all <see cref="Word"/>s from the WordsCollection and Frontier for specified <see cref="Project"/>
93+
/// </summary>
8594
/// <returns> A bool: success of operation </returns>
8695
public async Task<bool> DeleteAllWords(string projectId)
8796
{
@@ -130,7 +139,6 @@ private static void PopulateBlankWordTimes(Word word)
130139
/// If the Created or Modified time fields are blank, they will automatically calculated using the current
131140
/// time. This allows services to set or clear the values before creation to control these fields.
132141
/// </remarks>
133-
/// <param name="word"></param>
134142
/// <returns> The word created </returns>
135143
public async Task<Word> Create(Word word)
136144
{
@@ -148,7 +156,6 @@ public async Task<Word> Create(Word word)
148156
/// If the Created or Modified time fields are blank, they will automatically calculated using the current
149157
/// time. This allows services to set or clear the values before creation to control these fields.
150158
/// </remarks>
151-
/// <param name="words"></param>
152159
/// <returns> The words created </returns>
153160
public async Task<List<Word>> Create(List<Word> words)
154161
{

Backend/Services/WordService.cs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,44 @@ private async Task<Word> Add(string userId, Word word)
9393
return deletedWord.Id;
9494
}
9595

96-
/// <summary> Restores words to the Frontier </summary>
97-
/// <returns> A bool: true if successful, false if any don't exist or are already in the Frontier. </returns>
96+
/// <summary> Restores words to the Frontier that aren't in the Frontier </summary>
97+
/// <remarks>
98+
/// Aborts if any word can't be restored for any of the following reasons:
99+
/// doesn't exist; has Status.Deleted; or is already in the Frontier
100+
/// </remarks>
101+
/// <returns> A bool: true if all successfully restored; false if none restored. </returns>
98102
public async Task<bool> RestoreFrontierWords(string projectId, List<string> wordIds)
99103
{
100104
using var activity = OtelService.StartActivityWithTag(otelTagName, "restoring words to Frontier");
101105

102-
var words = new List<Word>();
103-
foreach (var id in wordIds)
106+
// Allow calls that don't specify any wordIds, but don't do any work.
107+
if (wordIds.Count == 0)
104108
{
105-
var word = await _wordRepo.GetWord(projectId, id);
106-
if (word is null || await _wordRepo.IsInFrontier(projectId, id))
107-
{
108-
return false;
109-
}
110-
words.Add(word);
109+
return true;
111110
}
112-
await _wordRepo.AddFrontier(words);
111+
112+
wordIds = wordIds.Distinct().ToList();
113+
114+
// Make sure none of the words are in the Frontier.
115+
if (await _wordRepo.AreInFrontier(projectId, wordIds, 1))
116+
{
117+
return false;
118+
}
119+
120+
// Make sure all the words exist and are valid.
121+
var wordsToRestore = await _wordRepo.GetWords(projectId, wordIds);
122+
if (wordsToRestore.Count != wordIds.Count)
123+
{
124+
return false;
125+
}
126+
if (wordsToRestore.Any(w => w.Accessibility == Status.Deleted))
127+
{
128+
// We should be restoring words that were removed from the Frontier,
129+
// and not their "Deleted" copies in the words collection.
130+
return false;
131+
}
132+
133+
await _wordRepo.AddFrontier(wordsToRestore);
113134
return true;
114135
}
115136

0 commit comments

Comments
 (0)