1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

[PM- 25678] Applications api endpoints (#16387)

* Adding the applications api endpoints and test cases

* Changing observable names
This commit is contained in:
Tom
2025-09-12 10:09:12 -04:00
committed by GitHub
parent 7ac75a6c52
commit f20ed9f0e9
4 changed files with 101 additions and 28 deletions

View File

@@ -44,10 +44,10 @@ describe("RiskInsightsApiService", () => {
expect(service).toBeTruthy();
});
it("should call apiService.send with correct parameters and return the response for getRiskInsightsReport ", (done) => {
it("Get Report: should call apiService.send with correct parameters and return the response for getRiskInsightsReport ", (done) => {
mockApiService.send.mockReturnValue(Promise.resolve(getRiskInsightsReportResponse));
service.getRiskInsightsReport(orgId).subscribe((result) => {
service.getRiskInsightsReport$(orgId).subscribe((result) => {
expect(result).toEqual(getRiskInsightsReportResponse);
expect(mockApiService.send).toHaveBeenCalledWith(
"GET",
@@ -60,21 +60,21 @@ describe("RiskInsightsApiService", () => {
});
});
it("should return null if apiService.send rejects with 404 error for getRiskInsightsReport", (done) => {
it("Get Report: should return null if apiService.send rejects with 404 error for getRiskInsightsReport", (done) => {
const error = { statusCode: 404 };
mockApiService.send.mockReturnValue(Promise.reject(error));
service.getRiskInsightsReport(orgId).subscribe((result) => {
service.getRiskInsightsReport$(orgId).subscribe((result) => {
expect(result).toBeNull();
done();
});
});
it("should throw error if apiService.send rejects with non-404 error for getRiskInsightsReport", (done) => {
it("Get Report: should throw error if apiService.send rejects with non-404 error for getRiskInsightsReport", (done) => {
const error = { statusCode: 500, message: "Server error" };
mockApiService.send.mockReturnValue(Promise.reject(error));
service.getRiskInsightsReport(orgId).subscribe({
service.getRiskInsightsReport$(orgId).subscribe({
next: () => {
// Should not reach here
fail("Expected error to be thrown");
@@ -95,10 +95,10 @@ describe("RiskInsightsApiService", () => {
});
});
it("should call apiService.send with correct parameters for saveRiskInsightsReport", (done) => {
it("Save Report: should call apiService.send with correct parameters for saveRiskInsightsReport", (done) => {
mockApiService.send.mockReturnValue(Promise.resolve(saveRiskInsightsReportResponse));
service.saveRiskInsightsReport(saveRiskInsightsReportRequest, orgId).subscribe((result) => {
service.saveRiskInsightsReport$(saveRiskInsightsReportRequest, orgId).subscribe((result) => {
expect(result).toEqual(saveRiskInsightsReportResponse);
expect(mockApiService.send).toHaveBeenCalledWith(
"POST",
@@ -111,11 +111,11 @@ describe("RiskInsightsApiService", () => {
});
});
it("should propagate errors from apiService.send for saveRiskInsightsReport - 1", (done) => {
it("Save Report: should propagate errors from apiService.send for saveRiskInsightsReport - 1", (done) => {
const error = { statusCode: 500, message: "Internal Server Error" };
mockApiService.send.mockReturnValue(Promise.reject(error));
service.saveRiskInsightsReport(saveRiskInsightsReportRequest, orgId).subscribe({
service.saveRiskInsightsReport$(saveRiskInsightsReportRequest, orgId).subscribe({
next: () => {
fail("Expected error to be thrown");
},
@@ -135,11 +135,11 @@ describe("RiskInsightsApiService", () => {
});
});
it("should propagate network errors from apiService.send for saveRiskInsightsReport - 2", (done) => {
it("Save Report: should propagate network errors from apiService.send for saveRiskInsightsReport - 2", (done) => {
const error = new Error("Network error");
mockApiService.send.mockReturnValue(Promise.reject(error));
service.saveRiskInsightsReport(saveRiskInsightsReportRequest, orgId).subscribe({
service.saveRiskInsightsReport$(saveRiskInsightsReportRequest, orgId).subscribe({
next: () => {
fail("Expected error to be thrown");
},
@@ -159,14 +159,14 @@ describe("RiskInsightsApiService", () => {
});
});
it("should call apiService.send with correct parameters and return an Observable", (done) => {
it("Get Summary: should call apiService.send with correct parameters and return an Observable", (done) => {
const minDate = new Date("2024-01-01");
const maxDate = new Date("2024-01-31");
const mockResponse: EncryptedDataModel[] = [{ encryptedData: "abc" } as EncryptedDataModel];
mockApiService.send.mockResolvedValueOnce(mockResponse);
service.getRiskInsightsSummary(orgId, minDate, maxDate).subscribe((result) => {
service.getRiskInsightsSummary$(orgId, minDate, maxDate).subscribe((result) => {
expect(mockApiService.send).toHaveBeenCalledWith(
"GET",
`/reports/organizations/${orgId.toString()}/data/summary?startDate=${minDate.toISOString().split("T")[0]}&endDate=${maxDate.toISOString().split("T")[0]}`,
@@ -179,13 +179,13 @@ describe("RiskInsightsApiService", () => {
});
});
it("should call apiService.send with correct parameters and return an Observable", (done) => {
it("Update Summary: should call apiService.send with correct parameters and return an Observable", (done) => {
const data: EncryptedDataModel = { encryptedData: "xyz" } as EncryptedDataModel;
const reportId = "report123" as OrganizationReportId;
mockApiService.send.mockResolvedValueOnce(undefined);
service.updateRiskInsightsSummary(data, orgId, reportId).subscribe((result) => {
service.updateRiskInsightsSummary$(data, orgId, reportId).subscribe((result) => {
expect(mockApiService.send).toHaveBeenCalledWith(
"PATCH",
`/reports/organizations/${orgId.toString()}/data/summary/${reportId.toString()}`,
@@ -197,4 +197,44 @@ describe("RiskInsightsApiService", () => {
done();
});
});
it("Get Applications: should call apiService.send with correct parameters and return an Observable", (done) => {
const reportId = "report123" as OrganizationReportId;
const mockResponse: EncryptedDataModel | null = { encryptedData: "abc" } as EncryptedDataModel;
mockApiService.send.mockResolvedValueOnce(mockResponse);
service.getRiskInsightsApplicationData$(orgId, reportId).subscribe((result) => {
expect(mockApiService.send).toHaveBeenCalledWith(
"GET",
`/reports/organizations/${orgId.toString()}/data/application/${reportId.toString()}`,
null,
true,
true,
);
expect(result).toEqual(mockResponse);
done();
});
});
it("Update Applications: should call apiService.send with correct parameters and return an Observable", (done) => {
const applicationData: EncryptedDataModel = { encryptedData: "xyz" } as EncryptedDataModel;
const reportId = "report123" as OrganizationReportId;
mockApiService.send.mockResolvedValueOnce(undefined);
service
.updateRiskInsightsApplicationData$(applicationData, orgId, reportId)
.subscribe((result) => {
expect(mockApiService.send).toHaveBeenCalledWith(
"PATCH",
`/reports/organizations/${orgId.toString()}/data/application/${reportId.toString()}`,
applicationData,
true,
true,
);
expect(result).toBeUndefined();
done();
});
});
});

View File

@@ -13,7 +13,7 @@ import {
export class RiskInsightsApiService {
constructor(private apiService: ApiService) {}
getRiskInsightsReport(orgId: OrganizationId): Observable<GetRiskInsightsReportResponse | null> {
getRiskInsightsReport$(orgId: OrganizationId): Observable<GetRiskInsightsReportResponse | null> {
const dbResponse = this.apiService
.send("GET", `/reports/organizations/${orgId.toString()}/latest`, null, true, true)
.catch((error: any): any => {
@@ -26,7 +26,7 @@ export class RiskInsightsApiService {
return from(dbResponse as Promise<GetRiskInsightsReportResponse>);
}
saveRiskInsightsReport(
saveRiskInsightsReport$(
request: SaveRiskInsightsReportRequest,
organizationId: OrganizationId,
): Observable<SaveRiskInsightsReportResponse> {
@@ -41,7 +41,7 @@ export class RiskInsightsApiService {
return from(dbResponse as Promise<SaveRiskInsightsReportResponse>);
}
getRiskInsightsSummary(
getRiskInsightsSummary$(
orgId: string,
minDate: Date,
maxDate: Date,
@@ -59,15 +59,46 @@ export class RiskInsightsApiService {
return from(dbResponse as Promise<EncryptedDataModel[]>);
}
updateRiskInsightsSummary(
data: EncryptedDataModel,
updateRiskInsightsSummary$(
summaryData: EncryptedDataModel,
organizationId: OrganizationId,
reportId: OrganizationReportId,
): Observable<void> {
const dbResponse = this.apiService.send(
"PATCH",
`/reports/organizations/${organizationId.toString()}/data/summary/${reportId.toString()}`,
data,
summaryData,
true,
true,
);
return from(dbResponse as Promise<void>);
}
getRiskInsightsApplicationData$(
orgId: OrganizationId,
reportId: OrganizationReportId,
): Observable<EncryptedDataModel | null> {
const dbResponse = this.apiService.send(
"GET",
`/reports/organizations/${orgId.toString()}/data/application/${reportId.toString()}`,
null,
true,
true,
);
return from(dbResponse as Promise<EncryptedDataModel | null>);
}
updateRiskInsightsApplicationData$(
applicationData: EncryptedDataModel,
orgId: OrganizationId,
reportId: OrganizationReportId,
): Observable<void> {
const dbResponse = this.apiService.send(
"PATCH",
`/reports/organizations/${orgId.toString()}/data/application/${reportId.toString()}`,
applicationData,
true,
true,
);

View File

@@ -171,7 +171,7 @@ describe("RiskInsightsReportService", () => {
);
const saveResponse = { id: "" }; // Simulating no ID in response
mockRiskInsightsApiService.saveRiskInsightsReport.mockReturnValue(of(saveResponse));
mockRiskInsightsApiService.saveRiskInsightsReport$.mockReturnValue(of(saveResponse));
const reportSubjectSpy = jest.spyOn((service as any).riskInsightsReportSubject, "next");
const summarySubjectSpy = jest.spyOn((service as any).riskInsightsSummarySubject, "next");
@@ -202,9 +202,11 @@ describe("RiskInsightsReportService", () => {
const organizationId = "orgId" as OrganizationId;
const userId = "userId" as UserId;
mockRiskInsightsApiService.getRiskInsightsReport.mockReturnValue(of(apiResponse));
mockRiskInsightsApiService.getRiskInsightsReport$.mockReturnValue(of(apiResponse));
service.getRiskInsightsReport(organizationId, userId);
expect(mockRiskInsightsApiService.getRiskInsightsReport).toHaveBeenCalledWith(organizationId);
expect(mockRiskInsightsApiService.getRiskInsightsReport$).toHaveBeenCalledWith(
organizationId,
);
expect(mockRiskInsightsEncryptionService.decryptRiskInsightsReport).toHaveBeenCalledWith(
organizationId,
userId,
@@ -231,7 +233,7 @@ describe("RiskInsightsReportService", () => {
const decryptedReport = {
data: [{ foo: "bar" }],
};
mockRiskInsightsApiService.getRiskInsightsReport.mockReturnValue(of(mockResponse));
mockRiskInsightsApiService.getRiskInsightsReport$.mockReturnValue(of(mockResponse));
mockRiskInsightsEncryptionService.decryptRiskInsightsReport.mockResolvedValue(
decryptedReport,
);

View File

@@ -216,7 +216,7 @@ export class RiskInsightsReportService {
getRiskInsightsReport(organizationId: OrganizationId, userId: UserId): void {
this.riskInsightsApiService
.getRiskInsightsReport(organizationId)
.getRiskInsightsReport$(organizationId)
.pipe(
switchMap((response) => {
if (!response) {
@@ -275,7 +275,7 @@ export class RiskInsightsReportService {
};
const response = await firstValueFrom(
this.riskInsightsApiService.saveRiskInsightsReport(saveRequest, organizationId),
this.riskInsightsApiService.saveRiskInsightsReport$(saveRequest, organizationId),
);
if (response && response.id) {