mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(API): Add user id information on push tracking when available (#14519)
This commit is contained in:
committed by
GitHub
parent
faecb47f15
commit
61957899e1
@@ -217,8 +217,10 @@ describe('Source Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should get tracking information from pre-push results', () => {
|
it('should get tracking information from pre-push results', () => {
|
||||||
const trackingResult = getTrackingInformationFromPrePushResult(pushResult);
|
const userId = 'userId';
|
||||||
|
const trackingResult = getTrackingInformationFromPrePushResult(userId, pushResult);
|
||||||
expect(trackingResult).toEqual({
|
expect(trackingResult).toEqual({
|
||||||
|
userId,
|
||||||
workflowsEligible: 3,
|
workflowsEligible: 3,
|
||||||
workflowsEligibleWithConflicts: 1,
|
workflowsEligibleWithConflicts: 1,
|
||||||
credsEligible: 1,
|
credsEligible: 1,
|
||||||
@@ -228,8 +230,10 @@ describe('Source Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should get tracking information from post-push results', () => {
|
it('should get tracking information from post-push results', () => {
|
||||||
const trackingResult = getTrackingInformationFromPostPushResult(pushResult);
|
const userId = 'userId';
|
||||||
|
const trackingResult = getTrackingInformationFromPostPushResult(userId, pushResult);
|
||||||
expect(trackingResult).toEqual({
|
expect(trackingResult).toEqual({
|
||||||
|
userId,
|
||||||
workflowsPushed: 2,
|
workflowsPushed: 2,
|
||||||
workflowsEligible: 3,
|
workflowsEligible: 3,
|
||||||
credsPushed: 1,
|
credsPushed: 1,
|
||||||
@@ -238,8 +242,10 @@ describe('Source Control', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should get tracking information from pull results', () => {
|
it('should get tracking information from pull results', () => {
|
||||||
const trackingResult = getTrackingInformationFromPullResult(pullResult);
|
const userId = 'userId';
|
||||||
|
const trackingResult = getTrackingInformationFromPullResult(userId, pullResult);
|
||||||
expect(trackingResult).toEqual({
|
expect(trackingResult).toEqual({
|
||||||
|
userId,
|
||||||
credConflicts: 1,
|
credConflicts: 1,
|
||||||
workflowConflicts: 1,
|
workflowConflicts: 1,
|
||||||
workflowUpdates: 3,
|
workflowUpdates: 3,
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import type { PullWorkFolderRequestDto, PushWorkFolderRequestDto } from '@n8n/api-types';
|
||||||
|
import type { Response } from 'express';
|
||||||
|
import { mock } from 'jest-mock-extended';
|
||||||
|
|
||||||
|
import type { EventService } from '@/events/event.service';
|
||||||
|
import type { AuthenticatedRequest } from '@/requests';
|
||||||
|
|
||||||
|
import type { SourceControlPreferencesService } from '../source-control-preferences.service.ee';
|
||||||
|
import { SourceControlController } from '../source-control.controller.ee';
|
||||||
|
import type { SourceControlService } from '../source-control.service.ee';
|
||||||
|
import type { SourceControlRequest } from '../types/requests';
|
||||||
|
import type { SourceControlGetStatus } from '../types/source-control-get-status';
|
||||||
|
|
||||||
|
describe('SourceControlController', () => {
|
||||||
|
let controller: SourceControlController;
|
||||||
|
let sourceControlService: SourceControlService;
|
||||||
|
let sourceControlPreferencesService: SourceControlPreferencesService;
|
||||||
|
let eventService: EventService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
sourceControlService = {
|
||||||
|
pushWorkfolder: jest.fn().mockResolvedValue({ statusCode: 200 }),
|
||||||
|
pullWorkfolder: jest.fn().mockResolvedValue({ statusCode: 200 }),
|
||||||
|
getStatus: jest.fn().mockResolvedValue([]),
|
||||||
|
setGitUserDetails: jest.fn(),
|
||||||
|
} as unknown as SourceControlService;
|
||||||
|
|
||||||
|
sourceControlPreferencesService = mock<SourceControlPreferencesService>();
|
||||||
|
eventService = mock<EventService>();
|
||||||
|
|
||||||
|
controller = new SourceControlController(
|
||||||
|
sourceControlService,
|
||||||
|
sourceControlPreferencesService,
|
||||||
|
eventService,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pushWorkfolder', () => {
|
||||||
|
it('should push workfolder with expected parameters', async () => {
|
||||||
|
const req = mock<AuthenticatedRequest>({
|
||||||
|
user: { firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
|
||||||
|
});
|
||||||
|
const res = mock<Response>();
|
||||||
|
const payload = { force: true } as PushWorkFolderRequestDto;
|
||||||
|
|
||||||
|
await controller.pushWorkfolder(req, res, payload);
|
||||||
|
expect(sourceControlService.setGitUserDetails).toHaveBeenCalledWith(
|
||||||
|
'John Doe',
|
||||||
|
'john.doe@example.com',
|
||||||
|
);
|
||||||
|
expect(sourceControlService.pushWorkfolder).toHaveBeenCalledWith(req.user, payload);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pullWorkfolder', () => {
|
||||||
|
it('should pull workfolder with expected parameters', async () => {
|
||||||
|
const req = mock<AuthenticatedRequest>({
|
||||||
|
user: { firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
|
||||||
|
});
|
||||||
|
const res = mock<Response>();
|
||||||
|
const payload = { force: true } as PullWorkFolderRequestDto;
|
||||||
|
|
||||||
|
await controller.pullWorkfolder(req, res, payload);
|
||||||
|
expect(sourceControlService.pullWorkfolder).toHaveBeenCalledWith(req.user, payload);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getStatus', () => {
|
||||||
|
it('should call getStatus with expected parameters', async () => {
|
||||||
|
const user = { firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' };
|
||||||
|
const query = {
|
||||||
|
direction: 'pull',
|
||||||
|
preferLocalVersion: true,
|
||||||
|
verbose: false,
|
||||||
|
} as SourceControlGetStatus;
|
||||||
|
const req = mock<SourceControlRequest.GetStatus>({
|
||||||
|
query,
|
||||||
|
user,
|
||||||
|
});
|
||||||
|
|
||||||
|
await controller.getStatus(req);
|
||||||
|
expect(sourceControlService.getStatus).toHaveBeenCalledWith(user, query);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('status', () => {
|
||||||
|
it('should call getStatus with expected parameters', async () => {
|
||||||
|
const user = { firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' };
|
||||||
|
const query = {
|
||||||
|
direction: 'pull',
|
||||||
|
preferLocalVersion: true,
|
||||||
|
verbose: false,
|
||||||
|
} as SourceControlGetStatus;
|
||||||
|
const req = mock<SourceControlRequest.GetStatus>({
|
||||||
|
query,
|
||||||
|
user,
|
||||||
|
});
|
||||||
|
|
||||||
|
await controller.status(req);
|
||||||
|
expect(sourceControlService.getStatus).toHaveBeenCalledWith(user, query);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -45,8 +45,9 @@ describe('SourceControlService', () => {
|
|||||||
|
|
||||||
describe('pushWorkfolder', () => {
|
describe('pushWorkfolder', () => {
|
||||||
it('should throw an error if a file is given that is not in the workfolder', async () => {
|
it('should throw an error if a file is given that is not in the workfolder', async () => {
|
||||||
|
const user = mock<User>();
|
||||||
await expect(
|
await expect(
|
||||||
sourceControlService.pushWorkfolder({
|
sourceControlService.pushWorkfolder(user, {
|
||||||
fileNames: [
|
fileNames: [
|
||||||
{
|
{
|
||||||
file: '/etc/passwd',
|
file: '/etc/passwd',
|
||||||
@@ -115,8 +116,9 @@ describe('SourceControlService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if a file is given that is not in the workfolder', async () => {
|
it('should throw an error if a file is given that is not in the workfolder', async () => {
|
||||||
|
const user = mock<User>();
|
||||||
await expect(
|
await expect(
|
||||||
sourceControlService.pushWorkfolder({
|
sourceControlService.pushWorkfolder(user, {
|
||||||
fileNames: [
|
fileNames: [
|
||||||
{
|
{
|
||||||
file: '/etc/passwd',
|
file: '/etc/passwd',
|
||||||
@@ -138,6 +140,7 @@ describe('SourceControlService', () => {
|
|||||||
describe('getStatus', () => {
|
describe('getStatus', () => {
|
||||||
it('conflict depends on the value of `direction`', async () => {
|
it('conflict depends on the value of `direction`', async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
|
const user = mock<User>();
|
||||||
|
|
||||||
// Define a credential that does only exist locally.
|
// Define a credential that does only exist locally.
|
||||||
// Pulling this would delete it so it should be marked as a conflict.
|
// Pulling this would delete it so it should be marked as a conflict.
|
||||||
@@ -200,13 +203,13 @@ describe('SourceControlService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ACT
|
// ACT
|
||||||
const pullResult = await sourceControlService.getStatus({
|
const pullResult = await sourceControlService.getStatus(user, {
|
||||||
direction: 'pull',
|
direction: 'pull',
|
||||||
verbose: false,
|
verbose: false,
|
||||||
preferLocalVersion: false,
|
preferLocalVersion: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const pushResult = await sourceControlService.getStatus({
|
const pushResult = await sourceControlService.getStatus(user, {
|
||||||
direction: 'push',
|
direction: 'push',
|
||||||
verbose: false,
|
verbose: false,
|
||||||
preferLocalVersion: false,
|
preferLocalVersion: false,
|
||||||
|
|||||||
@@ -131,9 +131,13 @@ function filterSourceControlledFilesUniqueIds(files: SourceControlledFile[]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTrackingInformationFromPullResult(result: SourceControlledFile[]) {
|
export function getTrackingInformationFromPullResult(
|
||||||
|
userId: string,
|
||||||
|
result: SourceControlledFile[],
|
||||||
|
) {
|
||||||
const uniques = filterSourceControlledFilesUniqueIds(result);
|
const uniques = filterSourceControlledFilesUniqueIds(result);
|
||||||
return {
|
return {
|
||||||
|
userId,
|
||||||
credConflicts: uniques.filter(
|
credConflicts: uniques.filter(
|
||||||
(file) =>
|
(file) =>
|
||||||
file.type === 'credential' && file.status === 'modified' && file.location === 'local',
|
file.type === 'credential' && file.status === 'modified' && file.location === 'local',
|
||||||
@@ -145,9 +149,13 @@ export function getTrackingInformationFromPullResult(result: SourceControlledFil
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTrackingInformationFromPrePushResult(result: SourceControlledFile[]) {
|
export function getTrackingInformationFromPrePushResult(
|
||||||
|
userId: string,
|
||||||
|
result: SourceControlledFile[],
|
||||||
|
) {
|
||||||
const uniques = filterSourceControlledFilesUniqueIds(result);
|
const uniques = filterSourceControlledFilesUniqueIds(result);
|
||||||
return {
|
return {
|
||||||
|
userId,
|
||||||
workflowsEligible: uniques.filter((file) => file.type === 'workflow').length,
|
workflowsEligible: uniques.filter((file) => file.type === 'workflow').length,
|
||||||
workflowsEligibleWithConflicts: uniques.filter(
|
workflowsEligibleWithConflicts: uniques.filter(
|
||||||
(file) => file.type === 'workflow' && file.conflict,
|
(file) => file.type === 'workflow' && file.conflict,
|
||||||
@@ -160,9 +168,13 @@ export function getTrackingInformationFromPrePushResult(result: SourceControlled
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTrackingInformationFromPostPushResult(result: SourceControlledFile[]) {
|
export function getTrackingInformationFromPostPushResult(
|
||||||
|
userId: string,
|
||||||
|
result: SourceControlledFile[],
|
||||||
|
) {
|
||||||
const uniques = filterSourceControlledFilesUniqueIds(result);
|
const uniques = filterSourceControlledFilesUniqueIds(result);
|
||||||
return {
|
return {
|
||||||
|
userId,
|
||||||
workflowsPushed: uniques.filter((file) => file.pushed && file.type === 'workflow').length ?? 0,
|
workflowsPushed: uniques.filter((file) => file.pushed && file.type === 'workflow').length ?? 0,
|
||||||
workflowsEligible: uniques.filter((file) => file.type === 'workflow').length ?? 0,
|
workflowsEligible: uniques.filter((file) => file.type === 'workflow').length ?? 0,
|
||||||
credsPushed:
|
credsPushed:
|
||||||
|
|||||||
@@ -175,7 +175,8 @@ export class SourceControlController {
|
|||||||
`${req.user.firstName} ${req.user.lastName}`,
|
`${req.user.firstName} ${req.user.lastName}`,
|
||||||
req.user.email,
|
req.user.email,
|
||||||
);
|
);
|
||||||
const result = await this.sourceControlService.pushWorkfolder(payload);
|
|
||||||
|
const result = await this.sourceControlService.pushWorkfolder(req.user, payload);
|
||||||
res.statusCode = result.statusCode;
|
res.statusCode = result.statusCode;
|
||||||
return result.statusResult;
|
return result.statusResult;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -213,6 +214,7 @@ export class SourceControlController {
|
|||||||
async getStatus(req: SourceControlRequest.GetStatus) {
|
async getStatus(req: SourceControlRequest.GetStatus) {
|
||||||
try {
|
try {
|
||||||
const result = (await this.sourceControlService.getStatus(
|
const result = (await this.sourceControlService.getStatus(
|
||||||
|
req.user,
|
||||||
new SourceControlGetStatus(req.query),
|
new SourceControlGetStatus(req.query),
|
||||||
)) as SourceControlledFile[];
|
)) as SourceControlledFile[];
|
||||||
return result;
|
return result;
|
||||||
@@ -224,7 +226,10 @@ export class SourceControlController {
|
|||||||
@Get('/status', { middlewares: [sourceControlLicensedMiddleware] })
|
@Get('/status', { middlewares: [sourceControlLicensedMiddleware] })
|
||||||
async status(req: SourceControlRequest.GetStatus) {
|
async status(req: SourceControlRequest.GetStatus) {
|
||||||
try {
|
try {
|
||||||
return await this.sourceControlService.getStatus(new SourceControlGetStatus(req.query));
|
return await this.sourceControlService.getStatus(
|
||||||
|
req.user,
|
||||||
|
new SourceControlGetStatus(req.query),
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new BadRequestError((error as { message: string }).message);
|
throw new BadRequestError((error as { message: string }).message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,10 @@ export class SourceControlService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async pushWorkfolder(options: PushWorkFolderRequestDto): Promise<{
|
async pushWorkfolder(
|
||||||
|
user: User,
|
||||||
|
options: PushWorkFolderRequestDto,
|
||||||
|
): Promise<{
|
||||||
statusCode: number;
|
statusCode: number;
|
||||||
pushResult: PushResult | undefined;
|
pushResult: PushResult | undefined;
|
||||||
statusResult: SourceControlledFile[];
|
statusResult: SourceControlledFile[];
|
||||||
@@ -239,7 +242,7 @@ export class SourceControlService {
|
|||||||
// only determine file status if not provided by the frontend
|
// only determine file status if not provided by the frontend
|
||||||
let statusResult: SourceControlledFile[] = filesToPush;
|
let statusResult: SourceControlledFile[] = filesToPush;
|
||||||
if (statusResult.length === 0) {
|
if (statusResult.length === 0) {
|
||||||
statusResult = (await this.getStatus({
|
statusResult = (await this.getStatus(user, {
|
||||||
direction: 'push',
|
direction: 'push',
|
||||||
verbose: false,
|
verbose: false,
|
||||||
preferLocalVersion: true,
|
preferLocalVersion: true,
|
||||||
@@ -332,7 +335,7 @@ export class SourceControlService {
|
|||||||
// #region Tracking Information
|
// #region Tracking Information
|
||||||
this.eventService.emit(
|
this.eventService.emit(
|
||||||
'source-control-user-finished-push-ui',
|
'source-control-user-finished-push-ui',
|
||||||
getTrackingInformationFromPostPushResult(statusResult),
|
getTrackingInformationFromPostPushResult(user.id, statusResult),
|
||||||
);
|
);
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
@@ -393,7 +396,7 @@ export class SourceControlService {
|
|||||||
): Promise<{ statusCode: number; statusResult: SourceControlledFile[] }> {
|
): Promise<{ statusCode: number; statusResult: SourceControlledFile[] }> {
|
||||||
await this.sanityCheck();
|
await this.sanityCheck();
|
||||||
|
|
||||||
const statusResult = (await this.getStatus({
|
const statusResult = (await this.getStatus(user, {
|
||||||
direction: 'pull',
|
direction: 'pull',
|
||||||
verbose: false,
|
verbose: false,
|
||||||
preferLocalVersion: false,
|
preferLocalVersion: false,
|
||||||
@@ -457,7 +460,7 @@ export class SourceControlService {
|
|||||||
// #region Tracking Information
|
// #region Tracking Information
|
||||||
this.eventService.emit(
|
this.eventService.emit(
|
||||||
'source-control-user-finished-pull-ui',
|
'source-control-user-finished-pull-ui',
|
||||||
getTrackingInformationFromPullResult(statusResult),
|
getTrackingInformationFromPullResult(user.id, statusResult),
|
||||||
);
|
);
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
@@ -477,7 +480,7 @@ export class SourceControlService {
|
|||||||
* @returns either SourceControlledFile[] if verbose is false,
|
* @returns either SourceControlledFile[] if verbose is false,
|
||||||
* or multiple SourceControlledFile[] with all determined differences for debugging purposes
|
* or multiple SourceControlledFile[] with all determined differences for debugging purposes
|
||||||
*/
|
*/
|
||||||
async getStatus(options: SourceControlGetStatus) {
|
async getStatus(user: User, options: SourceControlGetStatus) {
|
||||||
await this.sanityCheck();
|
await this.sanityCheck();
|
||||||
|
|
||||||
const sourceControlledFiles: SourceControlledFile[] = [];
|
const sourceControlledFiles: SourceControlledFile[] = [];
|
||||||
@@ -514,12 +517,12 @@ export class SourceControlService {
|
|||||||
if (options.direction === 'push') {
|
if (options.direction === 'push') {
|
||||||
this.eventService.emit(
|
this.eventService.emit(
|
||||||
'source-control-user-started-push-ui',
|
'source-control-user-started-push-ui',
|
||||||
getTrackingInformationFromPrePushResult(sourceControlledFiles),
|
getTrackingInformationFromPrePushResult(user.id, sourceControlledFiles),
|
||||||
);
|
);
|
||||||
} else if (options.direction === 'pull') {
|
} else if (options.direction === 'pull') {
|
||||||
this.eventService.emit(
|
this.eventService.emit(
|
||||||
'source-control-user-started-pull-ui',
|
'source-control-user-started-pull-ui',
|
||||||
getTrackingInformationFromPullResult(sourceControlledFiles),
|
getTrackingInformationFromPullResult(user.id, sourceControlledFiles),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|||||||
@@ -225,12 +225,14 @@ describe('TelemetryEventRelay', () => {
|
|||||||
|
|
||||||
it('should track on `source-control-user-finished-pull-ui` event', () => {
|
it('should track on `source-control-user-finished-pull-ui` event', () => {
|
||||||
const event: RelayEventMap['source-control-user-finished-pull-ui'] = {
|
const event: RelayEventMap['source-control-user-finished-pull-ui'] = {
|
||||||
|
userId: 'userId',
|
||||||
workflowUpdates: 3,
|
workflowUpdates: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
eventService.emit('source-control-user-finished-pull-ui', event);
|
eventService.emit('source-control-user-finished-pull-ui', event);
|
||||||
|
|
||||||
expect(telemetry.track).toHaveBeenCalledWith('User finished pull via UI', {
|
expect(telemetry.track).toHaveBeenCalledWith('User finished pull via UI', {
|
||||||
|
user_id: 'userId',
|
||||||
workflow_updates: 3,
|
workflow_updates: 3,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -251,6 +253,7 @@ describe('TelemetryEventRelay', () => {
|
|||||||
|
|
||||||
it('should track on `source-control-user-started-push-ui` event', () => {
|
it('should track on `source-control-user-started-push-ui` event', () => {
|
||||||
const event: RelayEventMap['source-control-user-started-push-ui'] = {
|
const event: RelayEventMap['source-control-user-started-push-ui'] = {
|
||||||
|
userId: 'userId',
|
||||||
workflowsEligible: 10,
|
workflowsEligible: 10,
|
||||||
workflowsEligibleWithConflicts: 2,
|
workflowsEligibleWithConflicts: 2,
|
||||||
credsEligible: 5,
|
credsEligible: 5,
|
||||||
@@ -261,6 +264,7 @@ describe('TelemetryEventRelay', () => {
|
|||||||
eventService.emit('source-control-user-started-push-ui', event);
|
eventService.emit('source-control-user-started-push-ui', event);
|
||||||
|
|
||||||
expect(telemetry.track).toHaveBeenCalledWith('User started push via UI', {
|
expect(telemetry.track).toHaveBeenCalledWith('User started push via UI', {
|
||||||
|
user_id: 'userId',
|
||||||
workflows_eligible: 10,
|
workflows_eligible: 10,
|
||||||
workflows_eligible_with_conflicts: 2,
|
workflows_eligible_with_conflicts: 2,
|
||||||
creds_eligible: 5,
|
creds_eligible: 5,
|
||||||
@@ -271,6 +275,7 @@ describe('TelemetryEventRelay', () => {
|
|||||||
|
|
||||||
it('should track on `source-control-user-finished-push-ui` event', () => {
|
it('should track on `source-control-user-finished-push-ui` event', () => {
|
||||||
const event: RelayEventMap['source-control-user-finished-push-ui'] = {
|
const event: RelayEventMap['source-control-user-finished-push-ui'] = {
|
||||||
|
userId: 'userId',
|
||||||
workflowsEligible: 10,
|
workflowsEligible: 10,
|
||||||
workflowsPushed: 8,
|
workflowsPushed: 8,
|
||||||
credsPushed: 5,
|
credsPushed: 5,
|
||||||
@@ -280,6 +285,7 @@ describe('TelemetryEventRelay', () => {
|
|||||||
eventService.emit('source-control-user-finished-push-ui', event);
|
eventService.emit('source-control-user-finished-push-ui', event);
|
||||||
|
|
||||||
expect(telemetry.track).toHaveBeenCalledWith('User finished push via UI', {
|
expect(telemetry.track).toHaveBeenCalledWith('User finished push via UI', {
|
||||||
|
user_id: 'userId',
|
||||||
workflows_eligible: 10,
|
workflows_eligible: 10,
|
||||||
workflows_pushed: 8,
|
workflows_pushed: 8,
|
||||||
creds_pushed: 5,
|
creds_pushed: 5,
|
||||||
|
|||||||
@@ -381,12 +381,14 @@ export type RelayEventMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
'source-control-user-started-pull-ui': {
|
'source-control-user-started-pull-ui': {
|
||||||
|
userId?: string;
|
||||||
workflowUpdates: number;
|
workflowUpdates: number;
|
||||||
workflowConflicts: number;
|
workflowConflicts: number;
|
||||||
credConflicts: number;
|
credConflicts: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
'source-control-user-finished-pull-ui': {
|
'source-control-user-finished-pull-ui': {
|
||||||
|
userId?: string;
|
||||||
workflowUpdates: number;
|
workflowUpdates: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -396,6 +398,7 @@ export type RelayEventMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
'source-control-user-started-push-ui': {
|
'source-control-user-started-push-ui': {
|
||||||
|
userId?: string;
|
||||||
workflowsEligible: number;
|
workflowsEligible: number;
|
||||||
workflowsEligibleWithConflicts: number;
|
workflowsEligibleWithConflicts: number;
|
||||||
credsEligible: number;
|
credsEligible: number;
|
||||||
@@ -404,6 +407,7 @@ export type RelayEventMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
'source-control-user-finished-push-ui': {
|
'source-control-user-finished-push-ui': {
|
||||||
|
userId: string;
|
||||||
workflowsEligible: number;
|
workflowsEligible: number;
|
||||||
workflowsPushed: number;
|
workflowsPushed: number;
|
||||||
credsPushed: number;
|
credsPushed: number;
|
||||||
|
|||||||
@@ -170,11 +170,13 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sourceControlUserStartedPullUi({
|
private sourceControlUserStartedPullUi({
|
||||||
|
userId,
|
||||||
workflowUpdates,
|
workflowUpdates,
|
||||||
workflowConflicts,
|
workflowConflicts,
|
||||||
credConflicts,
|
credConflicts,
|
||||||
}: RelayEventMap['source-control-user-started-pull-ui']) {
|
}: RelayEventMap['source-control-user-started-pull-ui']) {
|
||||||
this.telemetry.track('User started pull via UI', {
|
this.telemetry.track('User started pull via UI', {
|
||||||
|
user_id: userId,
|
||||||
workflow_updates: workflowUpdates,
|
workflow_updates: workflowUpdates,
|
||||||
workflow_conflicts: workflowConflicts,
|
workflow_conflicts: workflowConflicts,
|
||||||
cred_conflicts: credConflicts,
|
cred_conflicts: credConflicts,
|
||||||
@@ -182,9 +184,11 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sourceControlUserFinishedPullUi({
|
private sourceControlUserFinishedPullUi({
|
||||||
|
userId,
|
||||||
workflowUpdates,
|
workflowUpdates,
|
||||||
}: RelayEventMap['source-control-user-finished-pull-ui']) {
|
}: RelayEventMap['source-control-user-finished-pull-ui']) {
|
||||||
this.telemetry.track('User finished pull via UI', {
|
this.telemetry.track('User finished pull via UI', {
|
||||||
|
user_id: userId,
|
||||||
workflow_updates: workflowUpdates,
|
workflow_updates: workflowUpdates,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -200,6 +204,7 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sourceControlUserStartedPushUi({
|
private sourceControlUserStartedPushUi({
|
||||||
|
userId,
|
||||||
workflowsEligible,
|
workflowsEligible,
|
||||||
workflowsEligibleWithConflicts,
|
workflowsEligibleWithConflicts,
|
||||||
credsEligible,
|
credsEligible,
|
||||||
@@ -207,6 +212,7 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
variablesEligible,
|
variablesEligible,
|
||||||
}: RelayEventMap['source-control-user-started-push-ui']) {
|
}: RelayEventMap['source-control-user-started-push-ui']) {
|
||||||
this.telemetry.track('User started push via UI', {
|
this.telemetry.track('User started push via UI', {
|
||||||
|
user_id: userId,
|
||||||
workflows_eligible: workflowsEligible,
|
workflows_eligible: workflowsEligible,
|
||||||
workflows_eligible_with_conflicts: workflowsEligibleWithConflicts,
|
workflows_eligible_with_conflicts: workflowsEligibleWithConflicts,
|
||||||
creds_eligible: credsEligible,
|
creds_eligible: credsEligible,
|
||||||
@@ -216,12 +222,14 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sourceControlUserFinishedPushUi({
|
private sourceControlUserFinishedPushUi({
|
||||||
|
userId,
|
||||||
workflowsEligible,
|
workflowsEligible,
|
||||||
workflowsPushed,
|
workflowsPushed,
|
||||||
credsPushed,
|
credsPushed,
|
||||||
variablesPushed,
|
variablesPushed,
|
||||||
}: RelayEventMap['source-control-user-finished-push-ui']) {
|
}: RelayEventMap['source-control-user-finished-push-ui']) {
|
||||||
this.telemetry.track('User finished push via UI', {
|
this.telemetry.track('User finished push via UI', {
|
||||||
|
user_id: userId,
|
||||||
workflows_eligible: workflowsEligible,
|
workflows_eligible: workflowsEligible,
|
||||||
workflows_pushed: workflowsPushed,
|
workflows_pushed: workflowsPushed,
|
||||||
creds_pushed: credsPushed,
|
creds_pushed: credsPushed,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export = {
|
|||||||
|
|
||||||
if (result.statusCode === 200) {
|
if (result.statusCode === 200) {
|
||||||
Container.get(EventService).emit('source-control-user-pulled-api', {
|
Container.get(EventService).emit('source-control-user-pulled-api', {
|
||||||
...getTrackingInformationFromPullResult(result.statusResult),
|
...getTrackingInformationFromPullResult(req.user.id, result.statusResult),
|
||||||
forced: payload.force ?? false,
|
forced: payload.force ?? false,
|
||||||
});
|
});
|
||||||
return res.status(200).send(result.statusResult);
|
return res.status(200).send(result.statusResult);
|
||||||
|
|||||||
Reference in New Issue
Block a user