Skip to content

Commit

Permalink
SF-3157 Enable strict null checking in typescript (#2952)
Browse files Browse the repository at this point in the history
  • Loading branch information
RaymondLuong3 authored Jan 20, 2025
1 parent 299dd7f commit c5ca852
Show file tree
Hide file tree
Showing 43 changed files with 327 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ <h2>{{ t(canCreateQuestion ? "manage_questions" : "my_progress") }}</h2>
<mat-selection-list [multiple]="false">
@for (
questionDoc of getQuestionDocs(getTextDocIdType(text.bookNum, chapter.number));
track questionDoc.data.dataId
track questionDoc.data!.dataId
) {
<mat-list-item disableRipple>
<div class="flex">
Expand Down Expand Up @@ -349,7 +349,7 @@ <h2>{{ t("archived_questions") }}</h2>
<mat-selection-list [multiple]="false">
@for (
questionDoc of getQuestionDocs(getTextDocIdType(text.bookNum, chapter.number), true);
track questionDoc.data.dataId
track questionDoc.data!.dataId
) {
<mat-list-item disableRipple>
<div class="flex">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ describe('CheckingComponent', () => {
expect(question.isArchived).toBe(true);
expect(env.component.questionDocs.length).toEqual(13);
expect(env.component.questionVerseRefs.length).toEqual(13);
expect(env.component.questionsList.activeQuestionDoc.id).toBe('project01:q3Id');
expect(env.component.questionsList!.activeQuestionDoc!.id).toBe('project01:q3Id');
}));

it('opens a dialog when edit question is clicked', fakeAsync(() => {
Expand Down Expand Up @@ -1209,7 +1209,7 @@ describe('CheckingComponent', () => {
env.selectQuestion(6);
env.clickButton(env.getAnswerEditButton(0));
env.waitForSliderUpdate();
env.component.answersPanel.submit({ text: 'Answer 6 on question', audio: { status: 'reset' } });
env.component.answersPanel!.submit({ text: 'Answer 6 on question', audio: { status: 'reset' } });
env.waitForSliderUpdate();
verify(
mockedFileService.deleteFile(FileType.Audio, 'project01', QuestionDoc.COLLECTION, 'a6Id', CHECKER_USER.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ export class CheckingComponent extends DataLoadingComponent implements OnInit, A

get canShare(): boolean {
return (
this.projectDoc != null &&
this.projectDoc?.data != null &&
SF_PROJECT_RIGHTS.hasRight(
this.projectDoc.data,
this.userService.currentUserId,
Expand Down Expand Up @@ -600,7 +600,7 @@ export class CheckingComponent extends DataLoadingComponent implements OnInit, A
routeProjectId !== prevProjectId ||
routeScope !== prevScope ||
(routeScope !== 'all' && routeBookNum !== prevBookNum) ||
(routeScope === 'chapter' && parseInt(routeChapter) !== prevChapterNum)
(routeScope === 'chapter' && (routeChapter == null ? undefined : parseInt(routeChapter)) !== prevChapterNum)
) {
this.cleanup();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,10 @@ export class ImportQuestionsDialogComponent extends SubscriptionDisposable imple
ImportQuestionsConfirmationDialogComponent,
data
) as MatDialogRef<ImportQuestionsConfirmationDialogComponent, ImportQuestionsConfirmationDialogResult>;
(await lastValueFrom(dialogRef.afterClosed())).forEach(
(checked, index) => (changesToConfirm[index].checked = checked)
);
const result: ImportQuestionsConfirmationDialogResult | undefined = await lastValueFrom(dialogRef.afterClosed());
if (result != null) {
result.forEach((checked, index) => (changesToConfirm[index].checked = checked));
}
this.updateSelectAllCheckbox();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { compareProjectsForSorting, projectLabel } from '../shared/utils';
interface ConnectProjectFormValues {
settings: {
checking: boolean;
sourceParatextId: string;
sourceParatextId: string | null;
};
}

Expand Down Expand Up @@ -133,7 +133,12 @@ export class ConnectProjectComponent extends DataLoadingComponent implements OnI
if (!this.connectProjectForm.valid || this.projectsFromParatext == null) {
return;
}
const values = this.connectProjectForm.value as ConnectProjectFormValues;
const values: ConnectProjectFormValues = {
settings: {
checking: !!this.connectProjectForm.value.settings?.checking,
sourceParatextId: this.connectProjectForm.value.settings?.sourceParatextId ?? null
}
};
this.state = 'connecting';
const settings: SFProjectCreateSettings = {
paratextId: this.ptProjectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,11 @@ export class SFProjectService extends ProjectService<SFProject, SFProjectDoc> {
});
}

async onlineEventMetrics(projectId: string, pageIndex: number, pageSize: number): Promise<QueryResults<EventMetric>> {
async onlineEventMetrics(
projectId: string,
pageIndex: number,
pageSize: number
): Promise<QueryResults<EventMetric> | undefined> {
return await this.onlineInvoke<QueryResults<EventMetric>>('eventMetrics', { projectId, pageIndex, pageSize });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe('EventMetricsLogComponent', () => {
it('should not display table if invalid results', fakeAsync(() => {
const env = new TestEnvironment();
when(mockedProjectService.onlineEventMetrics(anything(), anything(), anything())).thenReturn(
Promise.resolve({ results: null, unpagedCount: 0 } as QueryResults<EventMetric>)
Promise.resolve({ results: null as unknown, unpagedCount: 0 } as QueryResults<EventMetric>)
);
env.wait();
env.wait();
Expand Down Expand Up @@ -206,7 +206,7 @@ class TestEnvironment {
when(mockedUserService.currentUserId).thenReturn('user01');
when(mockedAuthService.currentUserRoles).thenReturn([]);
when(mockDialogService.openMatDialog(EventMetricDialogComponent, anything())).thenReturn(instance(this.dialogRef));
when(mockedProjectService.onlineEventMetrics(anything(), anything(), anything())).thenReturn(null);
when(mockedProjectService.onlineEventMetrics(anything(), anything(), anything())).thenResolve(undefined);

this.fixture = TestBed.createComponent(EventMetricsLogComponent);
this.component = this.fixture.componentInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface Row {
eventType: string;
scope: string;
timeStamp: string;
userId: string;
userId?: string;
successful: boolean;
}

Expand Down Expand Up @@ -98,9 +98,9 @@ export class EventMetricsLogComponent extends DataLoadingComponent implements On
switchMap(async ([projectId, pageIndex, pageSize, isOnline]) => {
this.loadingStarted();
if (isOnline) {
var queryResults = await this.projectService.onlineEventMetrics(projectId, pageIndex, pageSize);
this.length = queryResults.unpagedCount;
if (Array.isArray(queryResults.results)) {
const queryResults = await this.projectService.onlineEventMetrics(projectId, pageIndex, pageSize);
this.length = queryResults?.unpagedCount ?? 0;
if (Array.isArray(queryResults?.results)) {
this.eventMetrics = queryResults.results as EventMetric[];
} else {
this.eventMetrics = [];
Expand Down Expand Up @@ -131,6 +131,10 @@ export class EventMetricsLogComponent extends DataLoadingComponent implements On

private generateRows(): void {
const rows: Row[] = [];
if (this.eventMetrics == null) {
this.rows = rows;
return;
}
for (const eventMetric of this.eventMetrics) {
rows.push({
dialogData: eventMetric,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ describe('ServalProjectComponent', () => {
}

getTrainingSourceBookNames(node: HTMLElement): string {
return node.querySelector('.training-source-range').textContent;
return node.querySelector('.training-source-range')?.textContent ?? '';
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class ServalProjectComponent extends DataLoadingComponent implements OnIn
columnsToDisplay = ['category', 'type', 'name', 'id'];
rows: Row[] = [];

trainingBooksByProject: ProjectAndRange[];
trainingBooksByProject: ProjectAndRange[] = [];
trainingFiles: string[] = [];
translationBooks: string[] = [];

Expand All @@ -87,7 +87,7 @@ export class ServalProjectComponent extends DataLoadingComponent implements OnIn
}

get eventLogLink(): string[] {
return ['/projects', this.activatedProjectService.projectId, 'event-log'];
return ['/projects', this.activatedProjectService.projectId!, 'event-log'];
}

get isOnline(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1008,12 +1008,15 @@ describe('SettingsComponent', () => {

it('should show Translation Suggestions when Based On is set', fakeAsync(() => {
const env = new TestEnvironment();
env.setupProject({
translateConfig: {
translationSuggestionsEnabled: false,
source: null
}
});
env.setupProject(
{
translateConfig: {
translationSuggestionsEnabled: false,
source: undefined
}
},
true
);
env.wait();
expect(env.translationSuggestionsCheckbox).toBeNull();
expect(env.basedOnSelectValue).toEqual('');
Expand Down Expand Up @@ -1102,12 +1105,14 @@ describe('SettingsComponent', () => {

it('Translation Suggestions should remain unchanged when Based On is changed', fakeAsync(() => {
const env = new TestEnvironment();
env.setupProject({
translateConfig: {
translationSuggestionsEnabled: false,
source: null
}
});
env.setupProject(
{
translateConfig: {
translationSuggestionsEnabled: false
}
},
true
);
env.wait();
expect(env.translationSuggestionsCheckbox).toBeNull();
expect(env.basedOnSelectValue).toEqual('');
Expand Down Expand Up @@ -1949,10 +1954,13 @@ class TestEnvironment {
}
});

setupProject(data: RecursivePartial<SFProject> = {}): void {
setupProject(data: RecursivePartial<SFProject> = {}, noSource = false): void {
const projectData = cloneDeep(this.testProject);
if (data.translateConfig != null) {
projectData.translateConfig = merge(projectData.translateConfig, data.translateConfig);
if (noSource) {
projectData.translateConfig.source = undefined;
}
}
if (data.checkingConfig != null) {
projectData.checkingConfig = merge(projectData.checkingConfig, data.checkingConfig);
Expand All @@ -1964,7 +1972,11 @@ class TestEnvironment {
projectData.sync = merge(projectData.sync, data.sync);
}
if (data.rolePermissions != null) {
projectData.rolePermissions = data.rolePermissions;
const rolePermissions: { [key: string]: string[] } = {};
for (const [role, permissions] of Object.entries(data.rolePermissions)) {
rolePermissions[role] = permissions?.filter(p => p != null) ?? [];
}
projectData.rolePermissions = rolePermissions;
}
this.realtimeService.addSnapshot<SFProject>(SFProjectDoc.COLLECTION, {
id: 'project01',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ export class SettingsComponent extends DataLoadingComponent implements OnInit {
): void {
if (this.settingChanged(newValue, setting)) {
const right = SF_PROJECT_RIGHTS.joinRight(SFProjectDomain.UserInvites, Operation.Create);
const permissions = new Set(this.projectDoc.data.rolePermissions[role] ?? []);
const permissions = new Set(this.projectDoc!.data!.rolePermissions[role] ?? []);
if (newValue[setting] === true) {
permissions.add(right);
} else {
Expand All @@ -487,7 +487,7 @@ export class SettingsComponent extends DataLoadingComponent implements OnInit {

this.checkUpdateStatus(
setting,
this.projectService.onlineSetRoleProjectPermissions(this.projectDoc.id, role, Array.from(permissions))
this.projectService.onlineSetRoleProjectPermissions(this.projectDoc!.id, role, Array.from(permissions))
);
this.previousFormValues = this.form.value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NgZone } from '@angular/core';
import { fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data';
import { TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
import { Chapter, TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito';
import { TestOnlineStatusModule } from 'xforge-common/test-online-status.module';
import { TestRealtimeModule } from 'xforge-common/test-realtime.module';
Expand Down Expand Up @@ -126,7 +126,7 @@ class TestEnvironment {
createTexts(): TextInfo[] {
const texts: TextInfo[] = [];
for (let book = 0; book < 200; book++) {
const chapters = [];
const chapters: Chapter[] = [];
for (let chapter = 0; chapter < 100; chapter++) {
chapters.push({ isValid: true, lastVerse: 1, number: chapter, permissions: {}, hasAudio: false });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NgZone } from '@angular/core';
import { discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data';
import { TextData } from 'realtime-server/lib/esm/scriptureforge/models/text-data';
import { TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
import { Chapter, TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
import { BehaviorSubject, of } from 'rxjs';
import { anything, deepEqual, instance, mock, when } from 'ts-mockito';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
Expand Down Expand Up @@ -232,7 +232,7 @@ class TestEnvironment {
createTexts(): TextInfo[] {
const texts: TextInfo[] = [];
for (let book = 0; book < this.numBooks; book++) {
const chapters = [];
const chapters: Chapter[] = [];
for (let chapter = 0; chapter < this.numChapters; chapter++) {
chapters.push({ isValid: true, lastVerse: 1, number: chapter, permissions: {}, hasAudio: false });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export abstract class ShareBaseComponent extends SubscriptionDisposable {
.filter(
info =>
info.permission &&
this.projectDoc?.data != null &&
SF_PROJECT_RIGHTS.hasRight(
this.projectDoc.data,
this.userService.currentUserId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ export class ShareControlComponent extends ShareBaseComponent {
}

return (
this.projectDoc?.data != null &&
SF_PROJECT_RIGHTS.hasRight(
this.projectDoc.data,
this.userService.currentUserId,
SFProjectDomain.UserInvites,
Operation.Create
) && this.userShareableRoles.includes(this.shareRole)
) &&
this.userShareableRoles.includes(this.shareRole)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,14 @@ export class ShareDialogComponent extends ShareBaseComponent {

get shareLinkUsageOptions(): ShareLinkType[] {
const options: ShareLinkType[] = [];
const canShare = SF_PROJECT_RIGHTS.hasRight(
this.projectDoc.data,
this.userService.currentUserId,
SFProjectDomain.UserInvites,
Operation.Create
);
const canShare =
this.projectDoc?.data != null &&
SF_PROJECT_RIGHTS.hasRight(
this.projectDoc.data,
this.userService.currentUserId,
SFProjectDomain.UserInvites,
Operation.Create
);
if (this.isProjectAdmin) {
options.push(ShareLinkType.Anyone);
options.push(ShareLinkType.Recipient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ export function registerScripture(): string[] {
if (this.stack[source].length === 0) {
return;
}
const stackItem: StackItem = this.stack[source].pop();
const stackItem: StackItem = this.stack[source].pop()!;
if (stackItem == null) {
return;
}
Expand All @@ -761,7 +761,7 @@ export function registerScripture(): string[] {
/**
* Transforms a range based on a delta. This function was copied from the Quill history module.
*/
function transformRange(range: Range | null, delta: Delta): Range {
function transformRange(range: Range | null, delta: Delta): Range | null {
if (!range) {
return range;
}
Expand Down Expand Up @@ -851,7 +851,7 @@ export function registerScripture(): string[] {
curIndex++;
}
} else if (op.retain != null) {
const retainCount: number = getRetainCount(op);
const retainCount: number = getRetainCount(op)!;
curIndex += retainCount;
changeIndex = curIndex;
}
Expand Down
Loading

0 comments on commit c5ca852

Please sign in to comment.