mirror of
https://github.com/bitwarden/browser
synced 2026-02-03 02:03:53 +00:00
Update test cases
This commit is contained in:
@@ -1,79 +1,83 @@
|
||||
export const mockMemberCipherDetailsResponse: { data: any[] } = {
|
||||
data: [
|
||||
{
|
||||
UserName: "David Brent",
|
||||
Email: "david.brent@wernhamhogg.uk",
|
||||
UsesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Tim Canterbury",
|
||||
Email: "tim.canterbury@wernhamhogg.uk",
|
||||
UsesKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Gareth Keenan",
|
||||
Email: "gareth.keenan@wernhamhogg.uk",
|
||||
UsesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm7",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Dawn Tinsley",
|
||||
Email: "dawn.tinsley@wernhamhogg.uk",
|
||||
UsesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Keith Bishop",
|
||||
Email: "keith.bishop@wernhamhogg.uk",
|
||||
UsesKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Chris Finch",
|
||||
Email: "chris.finch@wernhamhogg.uk",
|
||||
UsesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
},
|
||||
{
|
||||
UserName: "Chris Finch Tester",
|
||||
Email: "chris.finch@wernhamhogg.uk",
|
||||
UsesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { MemberCipherDetailsResponse } from "..";
|
||||
|
||||
export const mockMemberCipherDetailsResponse: MemberCipherDetailsResponse[] = [
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-1",
|
||||
userName: "David Brent",
|
||||
email: "david.brent@wernhamhogg.uk",
|
||||
useKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-2",
|
||||
userName: "Tim Canterbury",
|
||||
email: "tim.canterbury@wernhamhogg.uk",
|
||||
useKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-3",
|
||||
userName: "Gareth Keenan",
|
||||
email: "gareth.keenan@wernhamhogg.uk",
|
||||
useKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm7",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-4",
|
||||
userName: "Dawn Tinsley",
|
||||
email: "dawn.tinsley@wernhamhogg.uk",
|
||||
useKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-5",
|
||||
userName: "Keith Bishop",
|
||||
email: "keith.bishop@wernhamhogg.uk",
|
||||
useKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-1",
|
||||
userName: "Chris Finch",
|
||||
email: "chris.finch@wernhamhogg.uk",
|
||||
useKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
}),
|
||||
mock<MemberCipherDetailsResponse>({
|
||||
userGuid: "user-1",
|
||||
userName: "Mister Secure",
|
||||
email: "mister.secure@secureco.com",
|
||||
useKeyConnector: true,
|
||||
cipherIds: ["cbea34a8-bde4-46ad-9d19-b05001227tt1"],
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -7,8 +7,10 @@ import { MemberCipherDetailsResponse } from "..";
|
||||
import { ApplicationHealthReportDetailEnriched } from "../report-data-service.types";
|
||||
import {
|
||||
ApplicationHealthReportDetail,
|
||||
CipherHealthReport,
|
||||
OrganizationReportApplication,
|
||||
OrganizationReportSummary,
|
||||
PasswordHealthData,
|
||||
} from "../report-models";
|
||||
|
||||
const mockApplication1: ApplicationHealthReportDetail = {
|
||||
@@ -139,3 +141,41 @@ export const mockMemberDetails = [
|
||||
email: "user3@other.com",
|
||||
}),
|
||||
];
|
||||
|
||||
export const mockCipherHealthReports: CipherHealthReport[] = [
|
||||
{
|
||||
applications: ["app.com"],
|
||||
cipherMembers: [],
|
||||
healthData: createPasswordHealthData(0),
|
||||
cipher: mockCipherViews[0],
|
||||
},
|
||||
{
|
||||
applications: ["app.com"],
|
||||
cipherMembers: [],
|
||||
healthData: createPasswordHealthData(1),
|
||||
cipher: mockCipherViews[1],
|
||||
},
|
||||
{
|
||||
applications: ["other.com"],
|
||||
cipherMembers: [],
|
||||
healthData: createPasswordHealthData(2),
|
||||
cipher: mockCipherViews[2],
|
||||
},
|
||||
];
|
||||
|
||||
function createPasswordHealthData(reusedPasswordCount: number | null): PasswordHealthData {
|
||||
return {
|
||||
reusedPasswordCount: reusedPasswordCount ?? 0,
|
||||
weakPasswordDetail: {
|
||||
score: 0,
|
||||
detailValue: {
|
||||
label: "",
|
||||
badgeVariant: "info",
|
||||
},
|
||||
},
|
||||
exposedPasswordDetail: {
|
||||
cipherId: "",
|
||||
exposedXTimes: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,80 +2,9 @@ import { mock } from "jest-mock-extended";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
|
||||
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
||||
import { mockMemberCipherDetailsResponse } from "../../models/mocks/member-cipher-details-response.mock";
|
||||
|
||||
export const mockMemberCipherDetails: any = [
|
||||
{
|
||||
userName: "David Brent",
|
||||
email: "david.brent@wernhamhogg.uk",
|
||||
usesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Tim Canterbury",
|
||||
email: "tim.canterbury@wernhamhogg.uk",
|
||||
usesKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Gareth Keenan",
|
||||
email: "gareth.keenan@wernhamhogg.uk",
|
||||
usesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm7",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Dawn Tinsley",
|
||||
email: "dawn.tinsley@wernhamhogg.uk",
|
||||
usesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Keith Bishop",
|
||||
email: "keith.bishop@wernhamhogg.uk",
|
||||
usesKeyConnector: false,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab1",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001227nm5",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Chris Finch",
|
||||
email: "chris.finch@wernhamhogg.uk",
|
||||
usesKeyConnector: true,
|
||||
cipherIds: [
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228ab2",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228cd3",
|
||||
"cbea34a8-bde4-46ad-9d19-b05001228xy4",
|
||||
],
|
||||
},
|
||||
{
|
||||
userName: "Mister Secure",
|
||||
email: "mister.secure@secureco.com",
|
||||
usesKeyConnector: true,
|
||||
cipherIds: ["cbea34a8-bde4-46ad-9d19-b05001227tt1"],
|
||||
},
|
||||
];
|
||||
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
||||
|
||||
describe("Member Cipher Details API Service", () => {
|
||||
let memberCipherDetailsApiService: MemberCipherDetailsApiService;
|
||||
@@ -92,7 +21,7 @@ describe("Member Cipher Details API Service", () => {
|
||||
});
|
||||
|
||||
it("getMemberCipherDetails retrieves data", async () => {
|
||||
apiService.send.mockResolvedValue(mockMemberCipherDetails);
|
||||
apiService.send.mockResolvedValue(mockMemberCipherDetailsResponse);
|
||||
|
||||
const orgId = "1234";
|
||||
const result = await memberCipherDetailsApiService.getMemberCipherDetails(orgId);
|
||||
|
||||
@@ -240,10 +240,10 @@ describe("RiskInsightsApiService", () => {
|
||||
expect(mockApiService.send).toHaveBeenCalledWith(
|
||||
"PATCH",
|
||||
`/reports/organizations/${orgId.toString()}/data/application/${reportId.toString()}`,
|
||||
mockApplication,
|
||||
{ applicationData: mockApplication.encryptedString!, id: reportId, organizationId: orgId },
|
||||
true,
|
||||
true,
|
||||
);
|
||||
expect(result).toBeUndefined();
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { LogService } from "@bitwarden/logging";
|
||||
|
||||
import { createNewSummaryData } from "../../helpers";
|
||||
import { RiskInsightsData, SaveRiskInsightsReportResponse } from "../../models";
|
||||
import { mockMemberCipherDetailsResponse } from "../../models/mocks/member-cipher-details-response.mock";
|
||||
import {
|
||||
mockApplicationData,
|
||||
mockEnrichedReportData,
|
||||
@@ -32,6 +33,15 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
const mockUserId = "user-101" as UserId;
|
||||
const mockReportId = "report-1" as OrganizationReportId;
|
||||
|
||||
const reportState: RiskInsightsData = {
|
||||
id: mockReportId,
|
||||
reportData: [],
|
||||
summaryData: createNewSummaryData(),
|
||||
applicationData: [],
|
||||
creationDate: new Date(),
|
||||
};
|
||||
const mockCiphers = [{ id: "cipher-1" }] as any;
|
||||
|
||||
// Mock services
|
||||
const mockAccountService = mock<AccountService>({
|
||||
activeAccount$: of(mock<Account>({ id: mockUserId })),
|
||||
@@ -42,40 +52,56 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
const mockOrganizationService = mock<OrganizationService>();
|
||||
const mockCipherService = mock<CipherService>();
|
||||
const mockMemberCipherDetailsApiService = mock<MemberCipherDetailsApiService>();
|
||||
const mockPasswordHealthService = mock<PasswordHealthService>();
|
||||
let mockPasswordHealthService: PasswordHealthService;
|
||||
const mockReportApiService = mock<RiskInsightsApiService>();
|
||||
const mockReportService = mock<RiskInsightsReportService>();
|
||||
let mockReportService: RiskInsightsReportService;
|
||||
const mockRiskInsightsEncryptionService = mock<RiskInsightsEncryptionService>();
|
||||
const mockLogService = mock<LogService>();
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock pipes from constructor
|
||||
mockReportService = mock<RiskInsightsReportService>({
|
||||
generateApplicationsReport: jest.fn().mockReturnValue(mockEnrichedReportData),
|
||||
getApplicationsSummary: jest.fn().mockReturnValue(mockSummaryData),
|
||||
getOrganizationApplications: jest.fn().mockReturnValue(mockApplicationData),
|
||||
getRiskInsightsReport$: jest.fn().mockReturnValue(of(reportState)),
|
||||
saveRiskInsightsReport$: jest
|
||||
.fn()
|
||||
.mockReturnValue(of({ id: mockReportId } as SaveRiskInsightsReportResponse)),
|
||||
});
|
||||
// Arrange mocks for new flow
|
||||
mockMemberCipherDetailsApiService.getMemberCipherDetails.mockResolvedValue(
|
||||
mockMemberCipherDetailsResponse,
|
||||
);
|
||||
|
||||
mockPasswordHealthService = mock<PasswordHealthService>({
|
||||
auditPasswordLeaks$: jest.fn(() => of([])),
|
||||
isValidCipher: jest.fn().mockReturnValue(true),
|
||||
findWeakPasswordDetails: jest.fn().mockReturnValue(null),
|
||||
});
|
||||
|
||||
mockCipherService.getAllFromApiForOrganization.mockReturnValue(mockCiphers);
|
||||
|
||||
service = new RiskInsightsOrchestratorService(
|
||||
mockAccountService,
|
||||
mockCipherService,
|
||||
mockCriticalAppsService,
|
||||
mockLogService,
|
||||
mockMemberCipherDetailsApiService,
|
||||
mockOrganizationService,
|
||||
mockPasswordHealthService,
|
||||
mockReportApiService,
|
||||
mockReportService,
|
||||
mockRiskInsightsEncryptionService,
|
||||
mockLogService,
|
||||
);
|
||||
});
|
||||
|
||||
describe("fetchReport", () => {
|
||||
it("should call reportService.getRiskInsightsReport$ with correct org and user IDs and emit ReportState", (done) => {
|
||||
it("should call with correct org and user IDs and emit ReportState", (done) => {
|
||||
// Arrange
|
||||
const privateOrganizationDetailsSubject = service["_organizationDetailsSubject"];
|
||||
const privateUserIdSubject = service["_userIdSubject"];
|
||||
// Arrange
|
||||
const reportState: RiskInsightsData = {
|
||||
id: mockReportId,
|
||||
reportData: [],
|
||||
summaryData: createNewSummaryData(),
|
||||
applicationData: [],
|
||||
creationDate: new Date(),
|
||||
};
|
||||
mockReportService.getRiskInsightsReport$.mockReturnValueOnce(of(reportState));
|
||||
|
||||
// Set up organization and user context
|
||||
privateOrganizationDetailsSubject.next({
|
||||
organizationId: mockOrgId,
|
||||
@@ -100,18 +126,31 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
});
|
||||
|
||||
it("should emit error ReportState when getRiskInsightsReport$ throws", (done) => {
|
||||
const { _organizationDetailsSubject, _userIdSubject } = service as any;
|
||||
mockReportService.getRiskInsightsReport$.mockReturnValueOnce(
|
||||
// Simulate error
|
||||
throwError(() => new Error("API error")),
|
||||
// Setup error passed via constructor for this test case
|
||||
mockReportService.getRiskInsightsReport$ = jest
|
||||
.fn()
|
||||
.mockReturnValue(throwError(() => new Error("API error")));
|
||||
const testService = new RiskInsightsOrchestratorService(
|
||||
mockAccountService,
|
||||
mockCipherService,
|
||||
mockCriticalAppsService,
|
||||
mockLogService,
|
||||
mockMemberCipherDetailsApiService,
|
||||
mockOrganizationService,
|
||||
mockPasswordHealthService,
|
||||
mockReportApiService,
|
||||
mockReportService,
|
||||
mockRiskInsightsEncryptionService,
|
||||
);
|
||||
|
||||
const { _organizationDetailsSubject, _userIdSubject } = testService as any;
|
||||
_organizationDetailsSubject.next({
|
||||
organizationId: mockOrgId,
|
||||
organizationName: mockOrgName,
|
||||
});
|
||||
_userIdSubject.next(mockUserId);
|
||||
service.fetchReport();
|
||||
service.rawReportData$.subscribe((state) => {
|
||||
testService.fetchReport();
|
||||
testService.rawReportData$.subscribe((state) => {
|
||||
if (!state.loading) {
|
||||
expect(state.error).toBe("Failed to fetch report");
|
||||
expect(state.data).toBeNull();
|
||||
@@ -122,17 +161,11 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
});
|
||||
|
||||
describe("generateReport", () => {
|
||||
it("should call reportService.generateApplicationsReport and saveRiskInsightsReport$ and emit ReportState", (done) => {
|
||||
it("should generate report using member ciphers and password health, then save and emit ReportState", (done) => {
|
||||
const privateOrganizationDetailsSubject = service["_organizationDetailsSubject"];
|
||||
const privateUserIdSubject = service["_userIdSubject"];
|
||||
|
||||
// Arrange
|
||||
mockReportService.generateApplicationsReport.mockReturnValueOnce(mockEnrichedReportData);
|
||||
mockReportService.getApplicationsSummary.mockReturnValueOnce(mockSummaryData);
|
||||
mockReportService.getOrganizationApplications.mockReturnValueOnce(mockApplicationData);
|
||||
mockReportService.saveRiskInsightsReport$.mockReturnValueOnce(
|
||||
of({ id: mockReportId } as SaveRiskInsightsReportResponse),
|
||||
);
|
||||
// Set up ciphers in orchestrator
|
||||
privateOrganizationDetailsSubject.next({
|
||||
organizationId: mockOrgId,
|
||||
organizationName: mockOrgName,
|
||||
@@ -145,7 +178,10 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
// Assert
|
||||
service.rawReportData$.subscribe((state) => {
|
||||
if (!state.loading && state.data) {
|
||||
expect(mockReportService.generateApplicationsReport).toHaveBeenCalledWith(mockOrgId);
|
||||
expect(mockMemberCipherDetailsApiService.getMemberCipherDetails).toHaveBeenCalledWith(
|
||||
mockOrgId,
|
||||
);
|
||||
expect(mockReportService.generateApplicationsReport).toHaveBeenCalled();
|
||||
expect(mockReportService.saveRiskInsightsReport$).toHaveBeenCalledWith(
|
||||
mockEnrichedReportData,
|
||||
mockSummaryData,
|
||||
@@ -160,47 +196,22 @@ describe("RiskInsightsOrchestratorService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should emit error ReportState when saveRiskInsightsReport$ throws", (done) => {
|
||||
const privateOrganizationDetailsSubject = service["_organizationDetailsSubject"];
|
||||
const privateUserIdSubject = service["_userIdSubject"];
|
||||
describe("destroy", () => {
|
||||
it("should complete destroy$ subject and unsubscribe reportStateSubscription", () => {
|
||||
const privateDestroy = (service as any)._destroy$;
|
||||
const privateReportStateSubscription = (service as any)._reportStateSubscription;
|
||||
|
||||
mockReportService.generateApplicationsReport.mockReturnValueOnce(mockEnrichedReportData);
|
||||
mockReportService.getApplicationsSummary.mockReturnValueOnce(mockSummaryData);
|
||||
mockReportService.getOrganizationApplications.mockReturnValueOnce(mockApplicationData);
|
||||
mockReportService.saveRiskInsightsReport$.mockReturnValueOnce(
|
||||
throwError(() => new Error("Save error")),
|
||||
);
|
||||
privateOrganizationDetailsSubject.next({
|
||||
organizationId: mockOrgId,
|
||||
organizationName: mockOrgName,
|
||||
// Spy on the methods you expect to be called.
|
||||
const destroyCompleteSpy = jest.spyOn(privateDestroy, "complete");
|
||||
const unsubscribeSpy = jest.spyOn(privateReportStateSubscription, "unsubscribe");
|
||||
|
||||
// Execute the destroy method.
|
||||
service.destroy();
|
||||
|
||||
// Assert that the methods were called as expected.
|
||||
expect(destroyCompleteSpy).toHaveBeenCalled();
|
||||
expect(unsubscribeSpy).toHaveBeenCalled();
|
||||
});
|
||||
privateUserIdSubject.next(mockUserId);
|
||||
service.generateReport();
|
||||
service.rawReportData$.subscribe((state) => {
|
||||
if (!state.loading) {
|
||||
expect(state.error).toBe("Failed to generate or save report");
|
||||
expect(state.data).toBeNull();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("destroy", () => {
|
||||
it("should complete destroy$ subject and unsubscribe reportStateSubscription", () => {
|
||||
const privateDestroy = (service as any)._destroy$;
|
||||
const privateReportStateSubscription = (service as any)._reportStateSubscription;
|
||||
|
||||
// Spy on the methods you expect to be called.
|
||||
const destroyCompleteSpy = jest.spyOn(privateDestroy, "complete");
|
||||
const unsubscribeSpy = jest.spyOn(privateReportStateSubscription, "unsubscribe");
|
||||
|
||||
// Execute the destroy method.
|
||||
service.destroy();
|
||||
|
||||
// Assert that the methods were called as expected.
|
||||
expect(destroyCompleteSpy).toHaveBeenCalled();
|
||||
expect(unsubscribeSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,13 +109,13 @@ export class RiskInsightsOrchestratorService {
|
||||
private accountService: AccountService,
|
||||
private cipherService: CipherService,
|
||||
private criticalAppsService: CriticalAppsService,
|
||||
private logService: LogService,
|
||||
private memberCipherDetailsApiService: MemberCipherDetailsApiService,
|
||||
private organizationService: OrganizationService,
|
||||
private passwordHealthService: PasswordHealthService,
|
||||
private reportApiService: RiskInsightsApiService,
|
||||
private reportService: RiskInsightsReportService,
|
||||
private riskInsightsEncryptionService: RiskInsightsEncryptionService,
|
||||
private logService: LogService,
|
||||
) {
|
||||
this.logService.debug("[RiskInsightsOrchestratorService] Setting up");
|
||||
this._setupCriticalApplicationContext();
|
||||
@@ -283,8 +283,10 @@ export class RiskInsightsOrchestratorService {
|
||||
this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId),
|
||||
).pipe(map((memberCiphers) => flattenMemberDetails(memberCiphers)));
|
||||
|
||||
return forkJoin([this._ciphers$, memberCiphers$]).pipe(
|
||||
tap(() => this.logService.debug("[RiskInsightsOrchestratorService] Generating new report")),
|
||||
return forkJoin([this._ciphers$.pipe(take(1)), memberCiphers$]).pipe(
|
||||
tap(() => {
|
||||
this.logService.debug("[RiskInsightsOrchestratorService] Generating new report");
|
||||
}),
|
||||
switchMap(([ciphers, memberCiphers]) => this._getCipherHealth(ciphers ?? [], memberCiphers)),
|
||||
map((cipherHealthReports) =>
|
||||
this.reportService.generateApplicationsReport(cipherHealthReports),
|
||||
|
||||
@@ -12,15 +12,16 @@ import {
|
||||
SaveRiskInsightsReportResponse,
|
||||
} from "../../models/api-models.types";
|
||||
import { mockCiphers } from "../../models/mocks/ciphers.mock";
|
||||
import { mockMemberCipherDetailsResponse } from "../../models/mocks/member-cipher-details-response.mock";
|
||||
import {
|
||||
mockApplicationData,
|
||||
mockCipherHealthReports,
|
||||
mockCipherViews,
|
||||
mockMemberDetails,
|
||||
mockReportData,
|
||||
mockSummaryData,
|
||||
} from "../../models/mocks/mock-data";
|
||||
import { MemberCipherDetailsApiService } from "../api/member-cipher-details-api.service";
|
||||
import { mockMemberCipherDetails } from "../api/member-cipher-details-api.service.spec";
|
||||
import { RiskInsightsApiService } from "../api/risk-insights-api.service";
|
||||
|
||||
import { PasswordHealthService } from "./password-health.service";
|
||||
@@ -54,7 +55,9 @@ describe("RiskInsightsReportService", () => {
|
||||
beforeEach(() => {
|
||||
cipherService.getAllFromApiForOrganization.mockResolvedValue(mockCiphers);
|
||||
|
||||
memberCipherDetailsService.getMemberCipherDetails.mockResolvedValue(mockMemberCipherDetails);
|
||||
memberCipherDetailsService.getMemberCipherDetails.mockResolvedValue(
|
||||
mockMemberCipherDetailsResponse,
|
||||
);
|
||||
|
||||
// Mock PasswordHealthService methods
|
||||
mockPasswordHealthService.isValidCipher.mockImplementation((cipher: any) => {
|
||||
@@ -95,7 +98,7 @@ describe("RiskInsightsReportService", () => {
|
||||
cipherService.getAllFromApiForOrganization.mockResolvedValue(mockCipherViews);
|
||||
memberCipherDetailsService.getMemberCipherDetails.mockResolvedValue(mockMemberDetails);
|
||||
|
||||
const result = service.generateApplicationsReport("orgId" as any);
|
||||
const result = service.generateApplicationsReport(mockCipherHealthReports);
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
|
||||
// Should group by application name (trimmedUris)
|
||||
@@ -229,7 +232,11 @@ describe("RiskInsightsReportService", () => {
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(result).toEqual({ ...mockDecryptedData, creationDate: mockResponse.creationDate });
|
||||
expect(result).toEqual({
|
||||
...mockDecryptedData,
|
||||
id: mockResponse.id,
|
||||
creationDate: mockResponse.creationDate,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -57,13 +57,13 @@ import { RiskInsightsComponent } from "./risk-insights.component";
|
||||
AccountServiceAbstraction,
|
||||
CipherService,
|
||||
CriticalAppsService,
|
||||
LogService,
|
||||
MemberCipherDetailsApiService,
|
||||
OrganizationService,
|
||||
PasswordHealthService,
|
||||
RiskInsightsApiService,
|
||||
RiskInsightsReportService,
|
||||
RiskInsightsEncryptionService,
|
||||
LogService,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
|
||||
Reference in New Issue
Block a user