Convert all server events to new format, refactor admin events userAdminId, refactor tests

This commit is contained in:
ivanThePleasant 2022-08-11 15:56:39 +03:00
parent 7291d2e6cf
commit f8ac76491f
24 changed files with 150 additions and 60 deletions

View File

@ -9,7 +9,6 @@ import {
} from '@strapi/helper-plugin';
import { useQueries } from 'react-query';
import get from 'lodash/get';
import { hashAdminUser } from '@strapi/utils';
import packageJSON from '../../../../package.json';
import { useConfigurations } from '../../hooks';
import PluginsInitializer from '../PluginsInitializer';
@ -21,7 +20,7 @@ import {
fetchUserRoles,
} from './utils/api';
import checkLatestStrapiVersion from './utils/checkLatestStrapiVersion';
import { getFullName } from '../../utils';
import { getFullName, hashAdminUser } from '../../utils';
const strapiVersion = packageJSON.version;

View File

@ -19,7 +19,9 @@ const strapiVersion = packageJSON.version;
jest.mock('@strapi/helper-plugin', () => ({
...jest.requireActual('@strapi/helper-plugin'),
auth: { getUserInfo: () => ({ firstname: 'kai', lastname: 'doe' }) },
auth: {
getUserInfo: () => ({ firstname: 'kai', lastname: 'doe', email: 'testemail@strapi.io' }),
},
useGuidedTour: jest.fn(() => ({
setGuidedTourVisibility: jest.fn(),
})),

View File

@ -7,3 +7,4 @@ export { default as sortLinks } from './sortLinks';
export { default as getExistingActions } from './getExistingActions';
export { default as getRequestUrl } from './getRequestUrl';
export { default as getFullName } from './getFullName';
export { default as hashAdminUser } from './unique-admin-hash';

View File

@ -1,5 +1,3 @@
'use strict';
const crypto = require('crypto');
const hashAdminUser = payload => {

View File

@ -81,11 +81,23 @@ describe('Role controller', () => {
describe('updatePermissions', () => {
test('Fails on missing permissions input', async () => {
const findOne = jest.fn(() => Promise.resolve({ id: 1 }));
const hashAdminUser = jest.fn(() => 'testhash');
const ctx = createContext({
params: { id: 1 },
body: {},
});
const state = {
user: {
id: 1,
},
};
const ctx = createContext(
{
params: { id: 1 },
body: {},
},
{
state,
}
);
global.strapi = {
admin: {
@ -96,6 +108,9 @@ describe('Role controller', () => {
role: {
findOne,
},
'user-hash': {
hashAdminUser,
},
},
},
};
@ -112,13 +127,25 @@ describe('Role controller', () => {
test('Fails on missing action permission', async () => {
const findOne = jest.fn(() => Promise.resolve({ id: 1 }));
const hashAdminUser = jest.fn(() => 'testhash');
const ctx = createContext({
params: { id: 1 },
body: {
permissions: [{}],
const state = {
user: {
id: 1,
},
});
};
const ctx = createContext(
{
params: { id: 1 },
body: {
permissions: [{}],
},
},
{
state,
}
);
global.strapi = {
admin: {
services: {
@ -128,6 +155,9 @@ describe('Role controller', () => {
actionProvider: { get: jest.fn() },
conditionProvider: { values: jest.fn(() => []) },
},
'user-hash': {
hashAdminUser,
},
},
},
};
@ -146,6 +176,7 @@ describe('Role controller', () => {
const roleID = 1;
const findOneRole = jest.fn(() => Promise.resolve({ id: roleID }));
const assignPermissions = jest.fn((roleID, permissions) => Promise.resolve(permissions));
const hashAdminUser = jest.fn(() => 'testhash');
const inputPermissions = [
{
action: 'test',
@ -155,12 +186,23 @@ describe('Role controller', () => {
},
];
const ctx = createContext({
params: { id: roleID },
body: {
permissions: inputPermissions,
const state = {
user: {
id: 1,
},
});
};
const ctx = createContext(
{
params: { id: roleID },
body: {
permissions: inputPermissions,
},
},
{
state,
}
);
global.strapi = {
admin: {
@ -184,14 +226,20 @@ describe('Role controller', () => {
})),
},
},
'user-hash': {
hashAdminUser,
},
},
},
};
const adminUserId = hashAdminUser();
await roleController.updatePermissions(ctx);
expect(hashAdminUser).toHaveBeenCalledWith(ctx.state.user);
expect(findOneRole).toHaveBeenCalledWith({ id: roleID });
expect(assignPermissions).toHaveBeenCalledWith(roleID, inputPermissions);
expect(assignPermissions).toHaveBeenCalledWith(roleID, inputPermissions, adminUserId);
expect(ctx.body).toEqual({
data: inputPermissions,

View File

@ -15,7 +15,13 @@ describe('User Controller', () => {
test('Fails if user already exist', async () => {
const exists = jest.fn(() => Promise.resolve(true));
const ctx = createContext({ body });
const hashAdminUser = jest.fn(() => 'testhash');
const state = {
user: {
id: 1,
},
};
const ctx = createContext({ body }, { state });
global.strapi = {
admin: {
@ -23,6 +29,9 @@ describe('User Controller', () => {
user: {
exists,
},
'user-hash': {
hashAdminUser,
},
},
},
};
@ -44,8 +53,14 @@ describe('User Controller', () => {
const exists = jest.fn(() => Promise.resolve(false));
const sanitizeUser = jest.fn(user => Promise.resolve(user));
const created = jest.fn();
const ctx = createContext({ body }, { created });
const hashAdminUser = jest.fn(() => 'testhash');
const state = {
user: {
id: 1,
},
};
const ctx = createContext({ body }, { state, created });
console.log(ctx);
global.strapi = {
admin: {
services: {
@ -54,14 +69,20 @@ describe('User Controller', () => {
create,
sanitizeUser,
},
'user-hash': {
hashAdminUser,
},
},
},
};
const adminUserId = hashAdminUser();
await userController.create(ctx);
expect(hashAdminUser).toHaveBeenCalledWith(ctx.state.user);
expect(exists).toHaveBeenCalledWith({ email: body.email });
expect(create).toHaveBeenCalledWith(body);
expect(create).toHaveBeenCalledWith(body, adminUserId);
expect(sanitizeUser).toHaveBeenCalled();
expect(created).toHaveBeenCalled();
});

View File

@ -17,9 +17,14 @@ describe('Metrics', () => {
},
};
await metricsService.sendDidInviteUser();
const adminUserId = 'testhash';
expect(send).toHaveBeenCalledWith('didInviteUser', { numberOfRoles: 3, numberOfUsers: 2 });
await metricsService.sendDidInviteUser(adminUserId);
expect(send).toHaveBeenCalledWith(adminUserId, 'didInviteUser', {
numberOfRoles: 3,
numberOfUsers: 2,
});
expect(countUsers).toHaveBeenCalledWith();
expect(countRoles).toHaveBeenCalledWith();
});
@ -30,9 +35,11 @@ describe('Metrics', () => {
telemetry: { send },
};
await metricsService.sendDidUpdateRolePermissions();
const adminUserId = 'testhash';
expect(send).toHaveBeenCalledWith('didUpdateRolePermissions');
await metricsService.sendDidUpdateRolePermissions(adminUserId);
expect(send).toHaveBeenCalledWith(adminUserId, 'didUpdateRolePermissions');
});
test('didChangeInterfaceLanguage', async () => {
@ -51,7 +58,7 @@ describe('Metrics', () => {
await metricsService.sendDidChangeInterfaceLanguage();
expect(getLanguagesInUse).toHaveBeenCalledWith();
expect(send).toHaveBeenCalledWith('didChangeInterfaceLanguage', {
expect(send).toHaveBeenCalledWith('', 'didChangeInterfaceLanguage', {
languagesInUse: ['en', 'fr', 'en'],
});
});

View File

@ -14,7 +14,7 @@ const sendDidUpdateRolePermissions = async adminUserId => {
const sendDidChangeInterfaceLanguage = async () => {
const languagesInUse = await getService('user').getLanguagesInUse();
strapi.telemetry.send('didChangeInterfaceLanguage', { languagesInUse });
strapi.telemetry.send('', 'didChangeInterfaceLanguage', { languagesInUse });
};
module.exports = {

View File

@ -104,6 +104,7 @@ describe('Single Types', () => {
const createFn = jest.fn(() => ({}));
const sendTelemetry = jest.fn(() => ({}));
const hashAdminUser = jest.fn(() => 'testhash');
global.strapi = {
admin: {
@ -111,6 +112,9 @@ describe('Single Types', () => {
permission: {
createPermissionsManager,
},
'user-hash': {
hashAdminUser,
},
},
},
getModel() {
@ -165,8 +169,12 @@ describe('Single Types', () => {
{ state }
);
const adminUserId = hashAdminUser();
await singleTypes.createOrUpdate(ctx);
expect(hashAdminUser).toHaveBeenCalledWith(ctx.state.user);
expect(permissionChecker.cannot.create).toHaveBeenCalled();
expect(createFn).toHaveBeenCalledWith(
@ -179,7 +187,7 @@ describe('Single Types', () => {
{ params: {} }
);
expect(sendTelemetry).toHaveBeenCalledWith('didCreateFirstContentTypeEntry', {
expect(sendTelemetry).toHaveBeenCalledWith(adminUserId, 'didCreateFirstContentTypeEntry', {
model: modelUid,
});
});

View File

@ -65,6 +65,7 @@ module.exports = {
const { userAbility, user } = ctx.state;
const { model } = ctx.params;
const { body } = ctx.request;
const adminUserId = strapi.service('admin::user-hash').hashAdminUser(ctx.state.user);
const totalEntries = await strapi.query(model).count();
@ -87,7 +88,7 @@ module.exports = {
ctx.body = await permissionChecker.sanitizeOutput(entity);
if (totalEntries === 0) {
strapi.telemetry.send('didCreateFirstContentTypeEntry', { model });
strapi.telemetry.send(adminUserId, 'didCreateFirstContentTypeEntry', { model });
}
},

View File

@ -75,6 +75,7 @@ module.exports = {
const { userAbility } = ctx.state;
const { uid } = ctx.params;
const { body } = ctx.request;
const adminUserId = strapi.service('admin::user-hash').hashAdminUser(ctx.state.user);
const contentTypeService = getService('content-types');
const metricsService = getService('metrics');
@ -105,7 +106,7 @@ module.exports = {
const newConfiguration = await contentTypeService.updateConfiguration(contentType, input);
await metricsService.sendDidConfigureListView(contentType, newConfiguration);
await metricsService.sendDidConfigureListView(contentType, newConfiguration, adminUserId);
const confWithUpdatedMetadata = {
...newConfiguration,

View File

@ -46,6 +46,7 @@ module.exports = {
const { user, userAbility } = ctx.state;
const { model } = ctx.params;
const { body, query } = ctx.request;
const adminUserId = strapi.service('admin::user-hash').hashAdminUser(ctx.state.user);
const entityManager = getService('entity-manager');
const permissionChecker = getService('permission-checker').create({ userAbility, model });
@ -73,7 +74,7 @@ module.exports = {
const newEntity = await entityManager.create(sanitizedBody, model, { params: query });
ctx.body = await permissionChecker.sanitizeOutput(newEntity);
await strapi.telemetry.send('didCreateFirstContentTypeEntry', { model });
await strapi.telemetry.send(adminUserId, 'didCreateFirstContentTypeEntry', { model });
return;
}

View File

@ -66,11 +66,16 @@ describe('metrics', () => {
global.strapi = { telemetry: { send } };
metricsService = metricsServiceLoader({ strapi });
const [containsRelationalFields, displayedFields, displayedRelationalFields] = expectedResult;
const adminUserId = 'testhash';
await metricsService.sendDidConfigureListView(contentType, { layouts: { list } });
await metricsService.sendDidConfigureListView(
contentType,
{ layouts: { list } },
adminUserId
);
expect(send).toHaveBeenCalledTimes(1);
expect(send).toHaveBeenCalledWith('didConfigureListView', {
expect(send).toHaveBeenCalledWith(adminUserId, 'didConfigureListView', {
displayedFields,
containsRelationalFields,
displayedRelationalFields,

View File

@ -4,7 +4,7 @@ const { intersection, prop } = require('lodash/fp');
const { getRelationalFields } = require('@strapi/utils').relations;
module.exports = ({ strapi }) => {
const sendDidConfigureListView = async (contentType, configuration) => {
const sendDidConfigureListView = async (contentType, configuration, adminUserId) => {
const displayedFields = prop('length', configuration.layouts.list);
const relationalFields = getRelationalFields(contentType);
const displayedRelationalFields = intersection(relationalFields, configuration.layouts.list)
@ -22,7 +22,7 @@ module.exports = ({ strapi }) => {
}
try {
await strapi.telemetry.send('didConfigureListView', data);
await strapi.telemetry.send(adminUserId, 'didConfigureListView', data);
} catch (e) {
// silence
}

View File

@ -3,7 +3,6 @@
const _ = require('lodash');
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
const { hashAdminUser } = require('@strapi/utils');
const { getService } = require('../utils');
const {
validateContentTypeInput,
@ -48,6 +47,7 @@ module.exports = {
async createContentType(ctx) {
const { body } = ctx.request;
const adminUserId = strapi.service('admin::user-hash').hashAdminUser(ctx.state.user);
try {
await validateContentTypeInput(body);
@ -70,13 +70,10 @@ module.exports = {
hasDraftAndPublish: hasDraftAndPublish(contentType.schema),
};
const adminUserId = hashAdminUser(ctx);
console.log(adminUserId);
if (_.isEmpty(strapi.api)) {
await strapi.telemetry.send('didCreateFirstContentType', metricsProperties);
await strapi.telemetry.send(adminUserId, 'didCreateFirstContentType', metricsProperties);
} else {
await strapi.telemetry.send('didCreateContentType', metricsProperties);
await strapi.telemetry.send(adminUserId, 'didCreateContentType', metricsProperties);
}
setImmediate(() => strapi.reload());
@ -84,7 +81,7 @@ module.exports = {
ctx.send({ data: { uid: contentType.uid } }, 201);
} catch (error) {
strapi.log.error(error);
await strapi.telemetry.send('didNotCreateContentType', { error: error.message });
await strapi.telemetry.send(adminUserId, 'didNotCreateContentType', { error: error.message });
ctx.send({ error: error.message }, 400);
}
},

View File

@ -244,9 +244,9 @@ class Strapi {
if (shouldOpenAdmin && !isInitialized) {
try {
await utils.openBrowser(this.config);
this.telemetry.send('didOpenTab');
this.telemetry.send('', 'didOpenTab');
} catch (e) {
this.telemetry.send('didNotOpenTab');
this.telemetry.send('', 'didNotOpenTab');
}
}
}

View File

@ -91,16 +91,19 @@ describe('metrics', () => {
},
});
send('someEvent');
const adminUserId = 'testhash';
send(adminUserId, 'someEvent');
expect(fetch).toHaveBeenCalled();
expect(fetch.mock.calls[0][0]).toBe('https://analytics.strapi.io/track');
expect(fetch.mock.calls[0][1].method).toBe('POST');
expect(JSON.parse(fetch.mock.calls[0][1].body)).toMatchObject({
event: 'someEvent',
uuid: 'test',
adminUserId: 'testhash',
properties: {
projectType: 'Community',
projectId: 'test',
},
});

View File

@ -39,7 +39,7 @@ const createTelemetryInstance = strapi => {
register() {
if (!isDisabled) {
const pingCron = scheduleJob('0 0 12 * * *', () => sendEvent('ping'));
const pingCron = scheduleJob('0 0 12 * * *', () => sendEvent('', 'ping'));
crons.push(pingCron);
strapi.server.use(createMiddleware({ sendEvent }));
@ -52,6 +52,7 @@ const createTelemetryInstance = strapi => {
const sendLicenseCheck = () => {
return sendEvent(
'',
'didCheckLicense',
{
licenseInfo: {

View File

@ -16,7 +16,7 @@ const defaultQueryOpts = {
headers: { 'Content-Type': 'application/json' },
};
const ANALYTICS_URI = 'http://localhost:4000';
const ANALYTICS_URI = 'https://analytics.strapi.io';
/**
* Add properties from the package.json strapi key in the metadata

View File

@ -1,6 +1,5 @@
'use strict';
const { hashAdminUser } = require('@strapi/utils/lib');
const { getService } = require('../utils');
const { ACTIONS, FILE_MODEL_UID } = require('../constants');
const validateSettings = require('./validation/admin/settings');
@ -17,7 +16,7 @@ module.exports = {
}
const data = await validateSettings(body);
const adminUserId = hashAdminUser(ctx.state.user.email);
const adminUserId = strapi.service('admin::user-hash').hashAdminUser(ctx.state.user.email);
await getService('upload').setSettings(data, adminUserId);

View File

@ -92,7 +92,7 @@ module.exports = ({ strapi }) => ({
async sendMetrics() {
const metrics = await this.computeMetrics();
strapi.telemetry.send('didSendUploadPropertiesOnceAWeek', metrics);
strapi.telemetry.send('', 'didSendUploadPropertiesOnceAWeek', metrics);
const metricsInfoStored = await getMetricsStoreValue();
await setMetricsStoreValue({ ...metricsInfoStored, lastWeeklyUpdate: new Date().getTime() });

View File

@ -38,7 +38,6 @@ const pagination = require('./pagination');
const sanitize = require('./sanitize');
const traverseEntity = require('./traverse-entity');
const pipeAsync = require('./pipe-async');
const hashAdminUser = require('./unique-admin-hash');
module.exports = {
yup,
@ -80,5 +79,4 @@ module.exports = {
errors,
validateYupSchema,
validateYupSchemaSync,
hashAdminUser,
};

View File

@ -43,7 +43,7 @@ describe('Metrics', () => {
await sendDidInitializeEvent();
expect(strapi.telemetry.send).toHaveBeenCalledWith('didInitializeI18n', {
expect(strapi.telemetry.send).toHaveBeenCalledWith('', 'didInitializeI18n', {
numberOfContentTypes: 1,
});
});
@ -87,7 +87,7 @@ describe('Metrics', () => {
await sendDidUpdateI18nLocalesEvent();
expect(strapi.telemetry.send).toHaveBeenCalledWith('didUpdateI18nLocales', {
expect(strapi.telemetry.send).toHaveBeenCalledWith('', 'didUpdateI18nLocales', {
numberOfLocales: 3,
});
});

View File

@ -11,13 +11,13 @@ const sendDidInitializeEvent = async () => {
0
)(strapi.contentTypes);
await strapi.telemetry.send('didInitializeI18n', { numberOfContentTypes });
await strapi.telemetry.send('', 'didInitializeI18n', { numberOfContentTypes });
};
const sendDidUpdateI18nLocalesEvent = async () => {
const numberOfLocales = await getService('locales').count();
await strapi.telemetry.send('didUpdateI18nLocales', { numberOfLocales });
await strapi.telemetry.send('', 'didUpdateI18nLocales', { numberOfLocales });
};
module.exports = () => ({