diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html index 456aa8487d..ba2436b252 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html @@ -50,7 +50,7 @@
Alpha
', tag: tagGamma }, - { verseRef: 'MAT 1:1', content: 'Alpha again
', tag: tagAlpha } - ] - }, - { - id: 'note-2', - verseRef: 'MAT 1:2', - comments: [ - { verseRef: 'MAT 1:2', content: 'Beta
', tag: tagBeta }, - { verseRef: 'MAT 1:2', content: 'Beta duplicate
', tag: tagBeta } - ] - } - ]; + describe('Import from Paratext', () => { + it('disables import button when user is offline', fakeAsync(() => { + const env = new TestEnvironment({ offline: true }); + expect(env.importFromParatextButton.disabled).toBe(true); + expect(env.errorMessages[1]).toEqual('Importing from Paratext is not available offline.'); - const tags = env.collectParatextTagOptions(env.component, notes); - - expect(tags.length).toBe(3); - expect(tags.map(tag => tag.name)).toEqual(['Alpha', 'Beta', 'Gamma']); - expect(tags.map(tag => tag.id)).toEqual([1, 3, 2]); - })); + // simulate going back online + env.setOnline(true); + expect(env.importFromParatextButton.disabled).toBe(false); + })); - it('shows a message when no notes have tagged comments', fakeAsync(() => { - const env = new TestEnvironment(); - const notes: ParatextNote[] = [ - { - id: 'note-1', - verseRef: 'MAT 1:1', - comments: [{ verseRef: 'MAT 1:1', content: 'Note without tag
' }] - } - ]; - env.setParatextNotes(env.component, notes); - env.setParatextTagOptions(env.component, env.collectParatextTagOptions(env.component, notes)); - env.component.questionSource = 'paratext'; - env.component.showParatextTagSelector = true; - env.component.selectedParatextTagId = null; - env.component.errorState = undefined; - - env.fixture.detectChanges(); - tick(); + it('collects unique Paratext tags in alphabetical order', fakeAsync(() => { + const env = new TestEnvironment(); + const tagAlpha: ParatextNoteTag = { id: 1, name: 'Alpha' }; + const tagBeta: ParatextNoteTag = { id: 3, name: 'Beta' }; + const tagGamma: ParatextNoteTag = { id: 2, name: 'Gamma' }; + const notes: ParatextNote[] = [ + { + id: 'note-1', + verseRef: 'MAT 1:1', + comments: [ + { verseRef: 'MAT 1:1', content: 'Alpha
', tag: tagGamma }, + { verseRef: 'MAT 1:1', content: 'Alpha again
', tag: tagAlpha } + ] + }, + { + id: 'note-2', + verseRef: 'MAT 1:2', + comments: [ + { verseRef: 'MAT 1:2', content: 'Beta
', tag: tagBeta }, + { verseRef: 'MAT 1:2', content: 'Beta duplicate
', tag: tagBeta } + ] + } + ]; + + const tags = env.collectParatextTagOptions(env.component, notes); + + expect(tags.length).toBe(3); + expect(tags.map(tag => tag.name)).toEqual(['Alpha', 'Beta', 'Gamma']); + expect(tags.map(tag => tag.id)).toEqual([1, 3, 2]); + })); - expect(env.component.status).toBe('paratext_tag_selection'); - expect(env.getParatextTagMessage()).toBe('There are no tagged notes available to import.'); - })); + it('shows a message when no notes have tagged comments', fakeAsync(() => { + const env = new TestEnvironment(); + const notes: ParatextNote[] = [ + { + id: 'note-1', + verseRef: 'MAT 1:1', + comments: [{ verseRef: 'MAT 1:1', content: 'Note without tag
' }] + } + ]; + env.setParatextNotes(env.component, notes); + env.setParatextTagOptions(env.component, env.collectParatextTagOptions(env.component, notes)); + env.component.questionSource = 'paratext'; + env.component.showParatextTagSelector = true; + env.component.selectedParatextTagId = null; + env.component.errorState = undefined; + + env.fixture.detectChanges(); + tick(); + + expect(env.component.status).toBe('paratext_tag_selection'); + expect(env.getParatextTagMessage()).toBe('There are no tagged notes available to import.'); + })); - it('converts Paratext notes for the selected tag into questions', fakeAsync(() => { - const tagQuestions: ParatextNoteTag = { id: 7, name: 'Questions' }; - const notes: ParatextNote[] = [ - { - id: 'note-1', - verseRef: 'MAT 1:1', - comments: [ - { verseRef: 'MAT 1:1', content: 'Ignore
', tag: { id: 6, name: 'Other' } }, - { verseRef: 'MAT 1:1', content: 'Question text
', tag: tagQuestions } - ] - }, - { - id: 'note-2', - verseRef: 'MAT 1:2', - comments: [{ verseRef: 'MAT 1:2', content: 'Question 2
', tag: tagQuestions }] - }, - { - id: 'note-3', - verseRef: 'GEN 1:1', - comments: [{ verseRef: 'GEN 1:1', content: 'Different book
', tag: tagQuestions }] - } - ]; - const preexistingQuestion = TestEnvironment.createQuestionDocWithSource('note-1', new VerseRef('MAT 1:1'), 'text'); - const env = new TestEnvironment({ existingQuestions: [preexistingQuestion], paratextNotes: notes }); - env.setParatextNotes(env.component, notes); - env.setParatextTagOptions(env.component, env.collectParatextTagOptions(env.component, notes)); - env.component.selectedParatextTagId = tagQuestions.id; - env.component.questionSource = 'paratext'; - env.component.showParatextTagSelector = true; - - void env.component.confirmParatextTagSelection(); - tick(); - env.fixture.detectChanges(); - - expect(env.component.status).toBe('filter_notes'); - expect(env.component.filteredList.length).toBe(2); - const questionAlreadyImported = env.component.filteredList[0]; - expect(questionAlreadyImported.question.id).toBe('note-1'); - expect(questionAlreadyImported.question.text).toBe('Question text'); - expect(questionAlreadyImported.sfVersionOfQuestion).not.toBeUndefined(); - - expect(env.component.showDuplicateImportNote).toBeFalse(); - questionAlreadyImported.checked = true; - expect(env.component.showDuplicateImportNote).toBeTrue(); - })); + it('converts Paratext notes for the selected tag into questions', fakeAsync(() => { + const tagQuestions: ParatextNoteTag = { id: 7, name: 'Questions' }; + const notes: ParatextNote[] = [ + { + id: 'note-1', + verseRef: 'MAT 1:1', + comments: [ + { verseRef: 'MAT 1:1', content: 'Ignore
', tag: { id: 6, name: 'Other' } }, + { verseRef: 'MAT 1:1', content: 'Question text
', tag: tagQuestions } + ] + }, + { + id: 'note-2', + verseRef: 'MAT 1:2', + comments: [{ verseRef: 'MAT 1:2', content: 'Question 2
', tag: tagQuestions }] + }, + { + id: 'note-3', + verseRef: 'GEN 1:1', + comments: [{ verseRef: 'GEN 1:1', content: 'Different book
', tag: tagQuestions }] + } + ]; + const preexistingQuestion = TestEnvironment.createQuestionDocWithSource( + 'note-1', + new VerseRef('MAT 1:1'), + 'text' + ); + const env = new TestEnvironment({ existingQuestions: [preexistingQuestion], paratextNotes: notes }); + env.setParatextNotes(env.component, notes); + env.setParatextTagOptions(env.component, env.collectParatextTagOptions(env.component, notes)); + env.component.selectedParatextTagId = tagQuestions.id; + env.component.questionSource = 'paratext'; + env.component.showParatextTagSelector = true; + + void env.component.confirmParatextTagSelection(); + tick(); + env.fixture.detectChanges(); + + expect(env.component.status).toBe('filter_notes'); + expect(env.component.filteredList.length).toBe(2); + const questionAlreadyImported = env.component.filteredList[0]; + expect(questionAlreadyImported.question.id).toBe('note-1'); + expect(questionAlreadyImported.question.text).toBe('Question text'); + expect(questionAlreadyImported.sfVersionOfQuestion).not.toBeUndefined(); + + expect(env.component.showDuplicateImportNote).toBeFalse(); + questionAlreadyImported.checked = true; + expect(env.component.showDuplicateImportNote).toBeTrue(); + })); - it('shows an error when no Paratext project can be found', fakeAsync(() => { - const env = new TestEnvironment({ paratextProjects: [], paratextNotes: [] }); + it('shows an error when no Paratext project can be found', fakeAsync(() => { + const env = new TestEnvironment({ paratextProjects: [], paratextNotes: [] }); - env.click(env.importFromParatextButton); + env.click(env.importFromParatextButton); - expect(env.component.errorState).toBe('paratext_tag_load_error'); - expect(env.component.status).toBe('paratext_tag_load_error'); - expect(env.getParatextTagOptions(env.component).length).toBe(0); - })); + expect(env.component.errorState).toBe('paratext_tag_load_error'); + expect(env.component.status).toBe('paratext_tag_load_error'); + expect(env.getParatextTagOptions(env.component).length).toBe(0); + })); + }); }); class TestEnvironment { @@ -678,11 +694,13 @@ class TestEnvironment { ) { this.questions = options.transceleratorQuestions || this.questions; this.errorOnFetchQuestions = !!options.errorOnFetchQuestions; + + this.fixture = TestBed.createComponent(ChildViewContainerComponent); + if (options.offline === true) { - this.online$.next(false); + this.setOnline(false); } - this.fixture = TestBed.createComponent(ChildViewContainerComponent); if (options.editedQuestionIds) { this.simulateTransceleratorQuestionsAlreadyExisting(options.editedQuestionIds || []); } @@ -834,6 +852,7 @@ class TestEnvironment { setOnline(value: boolean): void { this.online$.next(value); + this.testOnlineStatusService.setIsOnline(value); tick(); this.fixture.detectChanges(); } diff --git a/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json b/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json index 7c8a43091d..b32c469766 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json +++ b/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json @@ -534,7 +534,7 @@ "network_error_transcelerator": "Network error fetching Transcelerator questions. Retrying ({{ count }}).", "next": "Next", "no_questions_available": "There are no questions for the books in this project.", - "no_transcelerator_offline": "Importing from Transcelerator is not available offline.", + "no_import_offline": "Importing from {{ method }} is not available offline.", "question_for_verse": "Question for verse {{ number }}", "question": "Question", "reference_from": "Reference from",