diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.html b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.html
index e4b6492c4f..95ff414a3d 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.html
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.html
@@ -2,7 +2,7 @@
{{ projectName }}
Back to Projects
Pre-Translation Configuration
-
+
Pre-Translation Drafting Enabled
@@ -23,7 +23,12 @@ Downloads
|
- |
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.spec.ts
index 8ed1c02a34..7380b4b0b2 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.spec.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.spec.ts
@@ -6,6 +6,9 @@ import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge
import { BehaviorSubject } from 'rxjs';
import { mock, verify, when } from 'ts-mockito';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
+import { OnlineStatusService } from 'xforge-common/online-status.service';
+import { TestOnlineStatusModule } from 'xforge-common/test-online-status.module';
+import { TestOnlineStatusService } from 'xforge-common/test-online-status.service';
import { TestRealtimeModule } from 'xforge-common/test-realtime.module';
import { configureTestingModule, TestTranslocoModule } from 'xforge-common/test-utils';
import { SFProjectProfileDoc } from '../core/models/sf-project-profile-doc';
@@ -22,15 +25,17 @@ const mockServalAdministrationService = mock(ServalAdministrationService);
describe('ServalProjectComponent', () => {
configureTestingModule(() => ({
imports: [
- ServalProjectComponent,
+ HttpClientTestingModule,
NoopAnimationsModule,
- TestTranslocoModule,
+ ServalProjectComponent,
+ TestOnlineStatusModule.forRoot(),
TestRealtimeModule.forRoot(SF_TYPE_REGISTRY),
- HttpClientTestingModule
+ TestTranslocoModule
],
providers: [
{ provide: ActivatedProjectService, useMock: mockActivatedProjectService },
{ provide: ActivatedRoute, useMock: mockActivatedRoute },
+ { provide: OnlineStatusService, useClass: TestOnlineStatusService },
{ provide: ServalAdministrationService, useMock: mockServalAdministrationService },
{ provide: SFProjectService, useMock: mockSFProjectService }
]
@@ -38,23 +43,45 @@ describe('ServalProjectComponent', () => {
it('should allow enabling pre-translation drafting', fakeAsync(() => {
const env = new TestEnvironment(false);
- expect(env.preTranslateCheckbox.checked).toBeFalsy();
+ expect(env.preTranslateCheckbox.checked).toBe(false);
env.clickElement(env.preTranslateCheckbox);
- expect(env.preTranslateCheckbox.checked).toBeTruthy();
+ expect(env.preTranslateCheckbox.checked).toBe(true);
verify(mockSFProjectService.onlineSetPreTranslate(env.mockProjectId, true)).once();
}));
it('should allow disabling pre-translation drafting', fakeAsync(() => {
const env = new TestEnvironment(true);
- expect(env.preTranslateCheckbox.checked).toBeTruthy();
+ expect(env.preTranslateCheckbox.checked).toBe(true);
env.clickElement(env.preTranslateCheckbox);
- expect(env.preTranslateCheckbox.checked).toBeFalsy();
+ expect(env.preTranslateCheckbox.checked).toBe(false);
verify(mockSFProjectService.onlineSetPreTranslate(env.mockProjectId, false)).once();
}));
+ it('should disable the pre-translation drafting checkbox when offline', fakeAsync(() => {
+ const env = new TestEnvironment(true);
+ env.onlineStatus = false;
+ expect(env.preTranslateCheckbox.disabled).toBe(true);
+ }));
+
+ it('should disable the download button when offline', fakeAsync(() => {
+ const env = new TestEnvironment(true);
+ env.onlineStatus = false;
+ expect(env.firstDownloadButton.innerText).toBe('Download');
+ expect(env.firstDownloadButton.disabled).toBe(true);
+ }));
+
+ it('should have a download button', fakeAsync(() => {
+ const env = new TestEnvironment(true);
+ expect(env.firstDownloadButton.innerText).toBe('Download');
+ expect(env.firstDownloadButton.disabled).toBe(false);
+ }));
+
class TestEnvironment {
readonly component: ServalProjectComponent;
readonly fixture: ComponentFixture;
+ readonly testOnlineStatusService: TestOnlineStatusService = TestBed.inject(
+ OnlineStatusService
+ ) as TestOnlineStatusService;
mockProjectId = 'project01';
@@ -106,6 +133,16 @@ describe('ServalProjectComponent', () => {
return this.fixture.nativeElement.querySelector('mat-checkbox input');
}
+ get firstDownloadButton(): HTMLInputElement {
+ return this.fixture.nativeElement.querySelector('td button');
+ }
+
+ set onlineStatus(hasConnection: boolean) {
+ this.testOnlineStatusService.setIsOnline(hasConnection);
+ tick();
+ this.fixture.detectChanges();
+ }
+
clickElement(button: HTMLElement): void {
button.click();
this.fixture.detectChanges();
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.ts
index 14c89a575d..1d93580eb0 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/serval-administration/serval-project.component.ts
@@ -5,6 +5,7 @@ import { catchError, lastValueFrom, tap, throwError } from 'rxjs';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
import { DataLoadingComponent } from 'xforge-common/data-loading-component';
import { NoticeService } from 'xforge-common/notice.service';
+import { OnlineStatusService } from 'xforge-common/online-status.service';
import { UICommonModule } from 'xforge-common/ui-common.module';
import { filterNullish } from 'xforge-common/util/rxjs-util';
import { SFProjectService } from '../core/sf-project.service';
@@ -36,12 +37,17 @@ export class ServalProjectComponent extends DataLoadingComponent implements OnIn
constructor(
private readonly activatedProjectService: ActivatedProjectService,
noticeService: NoticeService,
+ private readonly onlineStatusService: OnlineStatusService,
private readonly projectService: SFProjectService,
private readonly servalAdministrationService: ServalAdministrationService
) {
super(noticeService);
}
+ get isOnline(): boolean {
+ return this.onlineStatusService.isOnline;
+ }
+
ngOnInit(): void {
this.subscribe(
this.activatedProjectService.projectDoc$.pipe(