public void AddingLink_BetweenTwoWords_WillMergeTheirMasterWords(
            [Values(true, false)] bool wordBHasMoreTranslations,
            [Values(3, 5)] int amountOfWords,
            [Values(true, false)] bool cleanCache)
        {
            // Arrange
            PrepareTwoWords(out MasterWord masterA, out Word wordA, out MasterWord masterB, out Word wordB, (a, b) =>
            {
                if (amountOfWords == 5)
                {
                    new Word(a, "smh1", new Language("Any1"));
                    new Word(b, "smh2", new Language("Any2"));
                }

                if (wordBHasMoreTranslations)
                {
                    new Word(b, "smh", new Language("Any3"));
                }
                else
                {
                    new Word(a, "smh", new Language("Any3"));
                }
            });

            var mwcount = MasterWordsService.GetAll().Count();

            if (cleanCache)
            {
                RefreshServicesAndClearCache();
                wordA = WordsService.GetAll().First(w => w.ID == wordA.ID);
                wordB = WordsService.GetAll().First(w => w.ID == wordB.ID);
            }

            // Act
            WordsService.AddTranslation(wordA, wordB);

            // Assert
            var newA = WordsService.Get(wordA.ID);
            var newB = WordsService.Get(wordB.ID);
            var masterWordToSurvive = wordBHasMoreTranslations ? masterB : masterA;

            masterWordToSurvive = MasterWordsService.Get(masterWordToSurvive.ID);

            Assert.AreEqual(wordA.MasterWord, wordB.MasterWord, "Master words should be the same. Old ref");
            Assert.AreEqual(newA.MasterWord, newB.MasterWord, "Master words should be the same. New ref");
            Assert.AreEqual(amountOfWords, masterWordToSurvive.Words.Count, "all words should be on same master now");

            Assert.AreEqual(masterWordToSurvive, newB.MasterWord, "Master word was taken from incorrect word");
            Assert.AreEqual(mwcount - 1, MasterWordsService.GetAll().Count(), "Master word count should go down");
        }
        public void AddingLink_BetweenTwoWords_WillRefuseToMergeIfItsAlreadyTranslatedToThatLanguage(
            [Values(true, false)] bool inverseAddition,
            [Values(true, false)] bool cleanCache)
        {
            // Arrange
            var langEn  = new Language("English");
            var langEsp = new Language("Spanish");
            var langJp  = new Language("Japanese");

            var masterA = new MasterWord();
            var masterB = new MasterWord();

            var wordA1 = new Word(masterA, "Hi orig", langEn);
            var wordA2 = new Word(masterA, "Hola", langEsp);

            var wordB1 = new Word(masterA, "Hi duplicate", langEn);
            var wordB2 = new Word(masterA, "おはよう", langJp);

            MasterWordsService.Add(masterA);
            MasterWordsService.Add(masterB);

            if (cleanCache)
            {
                RefreshServicesAndClearCache();
                wordA2 = WordsService.GetAll().First(w => w.ID == wordA2.ID);
                wordB2 = WordsService.GetAll().First(w => w.ID == wordB2.ID);
            }

            // Act
            Assert.Throws <InvalidOperationException>(() =>
            {
                if (inverseAddition)
                {
                    WordsService.AddTranslation(wordA2, wordB2);
                }
                else
                {
                    WordsService.AddTranslation(wordB2, wordA2);
                }
            });
        }
        public void AddingLink_BetweenTwoWords_WillUpdateRefsInBooksToCorrectMasterWord(
            [Values(true, false)] bool bookLinksToBoth,
            [Values(true, false)] bool cleanCache)
        {
            // Arrange
            PrepareTwoWords(out MasterWord masterA, out Word wordA, out MasterWord masterB, out Word wordB);

            var book = new Book("name", wordA.Language);

            book.AddWord(masterB); // masterB is the one being destroyed

            if (bookLinksToBoth)
            {
                book.AddWord(masterA);
            }

            BooksService.Add(book);

            if (cleanCache)
            {
                RefreshServicesAndClearCache();
                wordA = WordsService.GetAll().First(w => w.ID == wordA.ID);
                wordB = WordsService.GetAll().First(w => w.ID == wordB.ID);
            }

            // Act
            WordsService.AddTranslation(wordA, wordB);

            // Assert
            book    = BooksService.Get(book.ID);
            masterA = MasterWordsService.Get(masterA.ID);
            masterB = MasterWordsService.Get(masterB.ID);

            Assert.AreEqual(masterA.ID, book.Words.First().ID, "Master words should be the same");
            Assert.AreEqual(1, book.Words.Count(), "Master words should be the same");

            Assert.AreEqual(book, masterA.Books.First(), "MasterA should link to correct book");
            Assert.IsNull(masterB, "MasterB should have been destroyed");
        }