Skip to content

Commit dc257df

Browse files
Merge pull request #2063 from AletheiaFact/New-tracking-page-to-verification-request
Public tracking page for verification request
2 parents c558655 + 9ad270f commit dc257df

30 files changed

+798
-95
lines changed

public/locales/en/tracking.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"verificationProgress": "Verification Request progress",
3+
"description_PRE_TRIAGE": "Verification request received and entered into the automated triage system. Initial analysis and severity assessment in progress.",
4+
"description_IN_TRIAGE": "Under review by the Aletheia team.",
5+
"description_POSTED": "Verification request complete and reviewed. Results posted.",
6+
"description_DECLINED": "Verification request declined following detailed analysis. The veracity of the information provided could not be confirmed.",
7+
"errorInvalidId": "Invalid verification request ID format.",
8+
"errorFetchData": "Failed to load tracking information. Please try again later."
9+
}

public/locales/en/verificationRequest.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@
6565
"showText": "Show",
6666
"startDate": "Start Date",
6767
"endDate": "End Date",
68-
"statusPreTriage": "Pre Triage",
69-
"statusInTriage": "In Triage",
70-
"statusPosted": "Posted",
71-
"statusDeclined": "Declined",
7268
"allPriorities": "All Priorities",
7369
"allSourceChannels": "All Source Channels",
7470
"priority": {
@@ -89,6 +85,11 @@
8985
"viewFullPage": "View full page",
9086
"automated_monitoring": "Automated Monitoring",
9187
"filterBySourceChannel": "Filter by Source Channel",
88+
"errorUpdatingStatus": "Error updating status:",
89+
"PRE_TRIAGE": "Pre Triage",
90+
"IN_TRIAGE": "In Triage",
91+
"POSTED": "Posted",
92+
"DECLINED": "Declined",
9293
"activity": {
9394
"Posted": "Verification request #{{hash}} verified and forwarded",
9495
"In Triage": "Verification request #{{hash}} in the verification process",
@@ -112,7 +113,6 @@
112113
"activitySubtitle": "Latest updates from the system",
113114
"errorLoading": "Error fetching statistics"
114115
},
115-
"errorUpdatingStatus": "Error updating status:",
116116
"identifiedPersonalities": "People Mentioned",
117117
"loadingPersonalities": "Loading personalities...",
118118
"personalitiesList": "List of identified personalities",

public/locales/pt/tracking.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"verificationProgress": "Progresso da Denúncia",
3+
"description_PRE_TRIAGE": "Denúncia recebida e inserida no sistema de triagem automatizada. Análise inicial e definição de severidade em progresso.",
4+
"description_IN_TRIAGE": "Sob revisão da equipe da Aletheia.",
5+
"description_POSTED": "Denúncia completa e revisada. Resultados publicados.",
6+
"description_DECLINED": "Denúncia negada após análise detalhada. Não foi possível confirmar a veracidade dos dados fornecidos.",
7+
"errorInvalidId": "O identificador da denúncia é inválido.",
8+
"errorFetchData": "Não foi possível carregar as informações de rastreamento. Tente novamente."
9+
}

public/locales/pt/verificationRequest.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@
6565
"showText": "Mostrar",
6666
"startDate": "Data inicial",
6767
"endDate": "Data final",
68-
"statusPreTriage": "Pré-Triagem",
69-
"statusInTriage": "Em Triagem",
70-
"statusPosted": "Publicado",
71-
"statusDeclined": "Recusado",
7268
"allPriorities": "Todas as Prioridades",
7369
"allSourceChannels": "Todos os Canais de Origem",
7470
"priority": {
@@ -89,6 +85,10 @@
8985
"viewFullPage": "Ver página completa",
9086
"automated_monitoring": "Monitoramento Automatizado",
9187
"filterBySourceChannel": "Filtrar por Canal de Origem",
88+
"PRE_TRIAGE": "Pré Triagem",
89+
"IN_TRIAGE": "Em Triagem",
90+
"POSTED": "Postado",
91+
"DECLINED": "Recusado",
9292
"activity": {
9393
"Posted": "Denúncia #{{hash}} verificada e encaminhada",
9494
"In Triage": "Denúncia #{{hash}} em processo de verificação",

server/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import { SessionOrM2MGuard } from "./auth/m2m-or-session.guard";
6464
import { M2MGuard } from "./auth/m2m.guard";
6565
import { CallbackDispatcherModule } from "./callback-dispatcher/callback-dispatcher.module";
6666
import { AiTaskModule } from "./ai-task/ai-task.module";
67+
import { TrackingModule } from "./tracking/tracking.module";
6768

6869
@Module({})
6970
export class AppModule implements NestModule {
@@ -120,6 +121,7 @@ export class AppModule implements NestModule {
120121
ReviewTaskModule,
121122
ClaimRevisionModule,
122123
HistoryModule,
124+
TrackingModule,
123125
StateEventModule,
124126
SourceModule,
125127
SpeechModule,

server/history/history.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,14 @@ export class HistoryService {
9898
const page = Math.max(Number(query.page) || 0, 0);
9999
const pageSize = Math.max(Number(query.pageSize) || 10, 1);
100100
const order = query.order === "desc" ? -1 : 1;
101-
const type = query.type || "";
102101

103102
const mongoQuery: HistoryItem = {
104103
targetId: Types.ObjectId(targetId),
105104
targetModel,
106105
};
107-
if (type) mongoQuery.type = type;
106+
if (query.type && query.type.length > 0) {
107+
mongoQuery.type = { $in: query.type };
108+
}
108109

109110
const result = await this.HistoryModel.aggregate([
110111
{ $match: mongoQuery },
@@ -180,7 +181,7 @@ export class HistoryService {
180181
page: 0,
181182
pageSize: 1,
182183
order: "desc",
183-
type: HistoryType.Hide,
184+
type: [HistoryType.Hide],
184185
});
185186

186187
return history[0]?.details?.after?.description || "";

server/history/types/history.interfaces.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface HistoryQuery {
1313
page?: number;
1414
pageSize?: number;
1515
order?: "asc" | "desc";
16-
type?: HistoryType;
16+
type?: HistoryType[];
1717
}
1818
interface HistoryResponse {
1919
history: HistoryItem[];
@@ -27,7 +27,7 @@ interface HistoryItem {
2727
targetId: Types.ObjectId;
2828
targetModel: TargetModel;
2929
user?: PerformedBy;
30-
type?: HistoryType;
30+
type?: HistoryType | { $in: HistoryType[] };
3131
details?: HistoryDetails;
3232
date?: Date | string;
3333
}

server/mocks/HistoryMock.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { VerificationRequestStatus } from "../verification-request/dto/types";
12
import { HistoryType, TargetModel } from "../history/schema/history.schema";
23
import { Types } from "mongoose";
34

@@ -8,10 +9,19 @@ export const historyServiceMock = {
89
export const mockHistoryItem = {
910
_id: "23432",
1011
targetId: new Types.ObjectId(),
11-
targetModel: TargetModel.Claim,
12+
targetModel: TargetModel.VerificationRequest,
1213
type: HistoryType.Update,
13-
details: { after: { description: "new" }, before: { description: "old" } },
1414
date: new Date(),
15+
details: {
16+
after: {
17+
description: "new",
18+
status: VerificationRequestStatus.PRE_TRIAGE,
19+
},
20+
before: {
21+
description: "old",
22+
status: VerificationRequestStatus.IN_TRIAGE,
23+
},
24+
},
1525
};
1626

1727
export const mockHistoryResponse = {
@@ -43,8 +53,3 @@ mockHistoryModel.mockImplementation(function (this: any, data) {
4353
});
4454

4555
mockHistoryModel.aggregate = jest.fn();
46-
47-
48-
49-
50-

server/mocks/TrackingMock.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { TrackingResponseDTO } from "../tracking/types/tracking.interfaces";
2+
import { VerificationRequestStatus } from "../verification-request/dto/types";
3+
4+
export const mockTrackingService = {
5+
getTrackingStatus: jest.fn(),
6+
};
7+
8+
export const mockResponse: TrackingResponseDTO = {
9+
currentStatus: VerificationRequestStatus.IN_TRIAGE,
10+
historyEvents: [
11+
{
12+
id: "history-1",
13+
status: VerificationRequestStatus.PRE_TRIAGE,
14+
date: new Date("2024-01-01T10:00:00Z"),
15+
},
16+
{
17+
id: "history-2",
18+
status: VerificationRequestStatus.IN_TRIAGE,
19+
date: new Date("2024-01-01T11:00:00Z"),
20+
},
21+
],
22+
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Test } from "@nestjs/testing";
2+
import { TrackingController } from "./tracking.controller";
3+
import { TrackingService } from "./tracking.service";
4+
import { BadRequestException } from "@nestjs/common";
5+
import { mockResponse, mockTrackingService } from "../mocks/TrackingMock";
6+
import { VerificationRequestStatus } from "../verification-request/dto/types";
7+
import { AbilitiesGuard } from "../auth/ability/abilities.guard";
8+
9+
describe("TrackingController (Unit)", () => {
10+
let controller: TrackingController;
11+
let trackingService: any;
12+
13+
beforeEach(async () => {
14+
const testingModule = await Test.createTestingModule({
15+
controllers: [TrackingController],
16+
providers: [{ provide: TrackingService, useValue: mockTrackingService }],
17+
})
18+
.overrideGuard(AbilitiesGuard)
19+
.useValue({})
20+
.compile();
21+
22+
controller = testingModule.get(TrackingController);
23+
trackingService = testingModule.get(TrackingService);
24+
});
25+
26+
beforeEach(() => {
27+
jest.clearAllMocks();
28+
});
29+
30+
describe("getTracking", () => {
31+
const validId = "507f1f77bcf86cd799439011";
32+
const invalidId = "123-id-invalido";
33+
34+
it("should return tracking status correctly (happy path)", async () => {
35+
trackingService.getTrackingStatus.mockResolvedValue(mockResponse);
36+
37+
const response = await controller.getTracking(validId);
38+
39+
expect(response).toEqual(mockResponse);
40+
expect(response.currentStatus).toBe(VerificationRequestStatus.IN_TRIAGE);
41+
expect(trackingService.getTrackingStatus).toHaveBeenCalledWith(validId);
42+
});
43+
44+
it("should throw BadRequestException if ID format is invalid", async () => {
45+
await expect(controller.getTracking(invalidId)).rejects.toThrow(
46+
BadRequestException
47+
);
48+
49+
expect(trackingService.getTrackingStatus).not.toHaveBeenCalled();
50+
});
51+
52+
it("should propagate service errors", async () => {
53+
trackingService.getTrackingStatus.mockRejectedValue(new Error("Database connection error"));
54+
55+
await expect(controller.getTracking(validId)).rejects.toThrow("Database connection error");
56+
});
57+
});
58+
});

0 commit comments

Comments
 (0)