/* * SonarQube * Copyright (C) 2009-2020 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* eslint-disable sonarjs/no-duplicate-string */ import { Location } from 'history'; import { InjectedRouter } from 'react-router'; import { createStore, Store } from 'redux'; import { DocumentationEntry } from '../apps/documentation/utils'; import { Exporter, Profile } from '../apps/quality-profiles/types'; import { ComponentQualifier } from '../types/component'; export function mockAlmApplication(overrides: Partial<T.AlmApplication> = {}): T.AlmApplication { return { backgroundColor: '#444444', iconPath: '/images/sonarcloud/github-white.svg', installationUrl: 'https://github.com/apps/greg-sonarcloud/installations/new', key: 'github', name: 'GitHub', ...overrides }; } export function mockAlmOrganization(overrides: Partial<T.AlmOrganization> = {}): T.AlmOrganization { return { avatar: 'http://example.com/avatar', almUrl: 'https://github.com/foo', description: 'description-foo', key: 'foo', name: 'foo', personal: false, privateRepos: 0, publicRepos: 3, url: 'http://example.com/foo', ...overrides }; } export function mockAnalysis(overrides: Partial<T.Analysis> = {}): T.Analysis { return { date: '2017-03-01T09:36:01+0100', events: [], key: 'foo', projectVersion: '1.0', ...overrides }; } export function mockParsedAnalysis(overrides: Partial<T.ParsedAnalysis> = {}): T.ParsedAnalysis { return { date: new Date('2017-03-01T09:37:01+0100'), events: [], key: 'foo', projectVersion: '1.0', ...overrides }; } export function mockAnalysisEvent(overrides: Partial<T.AnalysisEvent> = {}): T.AnalysisEvent { return { category: 'QUALITY_GATE', key: 'E11', description: 'Lorem ipsum dolor sit amet', name: 'Lorem ipsum', qualityGate: { status: 'ERROR', stillFailing: true, failing: [ { key: 'foo', name: 'Foo', branch: 'master' }, { key: 'bar', name: 'Bar', branch: 'feature/bar' } ] }, ...overrides }; } export function mockAppState(overrides: Partial<T.AppState> = {}): T.AppState { return { defaultOrganization: 'foo', edition: 'community', productionDatabase: true, qualifiers: ['TRK'], settings: {}, version: '1.0', ...overrides }; } export function mockBaseSysInfo(overrides: Partial<any> = {}): T.SysInfoBase { return { Health: 'GREEN' as T.HealthType, 'Health Causes': [], System: { Version: '7.8' }, Database: { Database: 'PostgreSQL', 'Database Version': '10.3', Username: 'sonar', URL: 'jdbc:postgresql://localhost/sonar', Driver: 'PostgreSQL JDBC Driver', 'Driver Version': '42.2.5' }, 'Compute Engine Tasks': { 'Total Pending': 0, 'Total In Progress': 0 }, 'Search State': { State: 'GREEN', Nodes: 3 }, 'Search Indexes': { 'Index components - Docs': 30445, 'Index components - Shards': 10 }, ...overrides }; } export function mockClusterSysInfo(overrides: Partial<any> = {}): T.SysInfoCluster { const baseInfo = mockBaseSysInfo(overrides); return { ...baseInfo, System: { ...baseInfo.System, 'High Availability': true, 'Server ID': 'asd564-asd54a-5dsfg45' }, Settings: { 'sonar.cluster.enabled': 'true', 'sonar.cluster.node.name': 'server9.example.com' }, 'Application Nodes': [ { Name: 'server9.example.com', Host: '10.0.0.0', Health: 'GREEN' as T.HealthType, 'Health Causes': [], System: { Version: '7.8' }, Plugins: { java: '5.13.0.17924 [SonarJava]' }, 'Web JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 122 }, 'Web Database Connection': { 'Pool Active Connections': 1 }, 'Web Logging': { 'Logs Level': 'DEBUG' }, 'Web JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' }, 'Compute Engine Tasks': { Pending: 0, 'In Progress': 0 }, 'Compute Engine JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 78 }, 'Compute Engine Database Connection': { 'Pool Initial Size': 0, 'Pool Active Connections': 0 }, 'Compute Engine Logging': { 'Logs Level': 'INFO' }, 'Compute Engine JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' } }, { Name: 'server9.example.com', Host: '10.0.0.0', Health: 'GREEN' as T.HealthType, 'Health Causes': [], System: { Version: '7.8' }, Plugins: { java: '5.13.0.17924 [SonarJava]' }, 'Web JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 111 }, 'Web Database Connection': { 'Pool Active Connections': 0, 'Pool Max Connections': 60 }, 'Web Logging': { 'Logs Level': 'INFO' }, 'Web JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' }, 'Compute Engine Tasks': { Pending: 0, 'In Progress': 0 }, 'Compute Engine JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 89 }, 'Compute Engine Database Connection': { 'Pool Initial Size': 0, 'Pool Active Connections': 0 }, 'Compute Engine Logging': { 'Logs Level': 'INFO' }, 'Compute Engine JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' } } ], 'Search Nodes': [ { Name: 'server.example.com', Host: '10.0.0.0', 'Search State': { 'CPU Usage (%)': 0, 'Disk Available': '93 GB' } }, { Name: 'server.example.com', Host: '10.0.0.0', 'Search State': { 'CPU Usage (%)': 0, 'Disk Available': '93 GB' } }, { Name: 'server.example.com', Host: '10.0.0.0', 'Search State': { 'CPU Usage (%)': 0, 'Disk Available': '93 GB' } } ], Statistics: { ncloc: 989880 }, ...overrides }; } export function mockComponent(overrides: Partial<T.Component> = {}): T.Component { return { breadcrumbs: [], key: 'my-project', name: 'MyProject', organization: 'foo', qualifier: ComponentQualifier.Project, qualityGate: { isDefault: true, key: '30', name: 'Sonar way' }, qualityProfiles: [ { deleted: false, key: 'my-qp', language: 'ts', name: 'Sonar way' } ], tags: [], ...overrides }; } export function mockComponentMeasure( file = false, overrides: Partial<T.ComponentMeasure> = {} ): T.ComponentMeasure { if (file) { return { key: 'foo:src/index.tsx', name: 'index.tsx', qualifier: 'FIL', path: 'src/index.tsx', measures: [{ metric: 'bugs', value: '1', bestValue: false }], ...overrides }; } return { key: 'foo', name: 'Foo', qualifier: 'TRK', measures: [{ metric: 'bugs', value: '12', bestValue: false }], ...overrides }; } export function mockCondition(overrides: Partial<T.Condition> = {}): T.Condition { return { error: '10', id: 1, metric: 'coverage', op: 'LT', ...overrides }; } export function mockSnippetsByComponent( component = 'main.js', lines: number[] = [16] ): T.SnippetsByComponent { const sources = lines.reduce((lines: { [key: number]: T.SourceLine }, line) => { lines[line] = mockSourceLine({ line }); return lines; }, {}); return { component: mockSourceViewerFile({ key: component, path: component }), sources }; } export function mockSourceLine(overrides: Partial<T.SourceLine> = {}): T.SourceLine { return { line: 16, code: '<span class="k">import</span> java.util.<span class="sym-9 sym">ArrayList</span>;', coverageStatus: 'covered', coveredConditions: 2, scmRevision: '80f564becc0c0a1c9abaa006eca83a4fd278c3f0', scmAuthor: 'simon.brandhof@sonarsource.com', scmDate: '2018-12-11T10:48:39+0100', duplicated: false, isNew: true, ...overrides }; } export function mockCurrentUser(overrides: Partial<T.CurrentUser> = {}): T.CurrentUser { return { isLoggedIn: false, ...overrides }; } export function mockLoggedInUser(overrides: Partial<T.LoggedInUser> = {}): T.LoggedInUser { return { groups: [], isLoggedIn: true, login: 'luke', name: 'Skywalker', scmAccounts: [], ...overrides }; } export function mockGroup(overrides: Partial<T.Group> = {}): T.Group { return { id: 1, membersCount: 1, name: 'Foo', ...overrides }; } export function mockEvent(overrides = {}) { return { target: { blur() {} }, currentTarget: { blur() {} }, preventDefault() {}, stopPropagation() {}, ...overrides } as any; } export function mockIssue(withLocations = false, overrides: Partial<T.Issue> = {}) { const issue: T.Issue = { actions: [], component: 'main.js', componentLongName: 'main.js', componentQualifier: 'FIL', componentUuid: 'foo1234', creationDate: '2017-03-01T09:36:01+0100', flows: [], fromHotspot: false, key: 'AVsae-CQS-9G3txfbFN2', line: 25, message: 'Reduce the number of conditional operators (4) used in the expression', organization: 'myorg', project: 'myproject', projectKey: 'foo', projectName: 'Foo', projectOrganization: 'org', rule: 'javascript:S1067', ruleName: 'foo', secondaryLocations: [], severity: 'MAJOR', status: 'OPEN', textRange: { startLine: 25, endLine: 26, startOffset: 0, endOffset: 15 }, transitions: [], type: 'BUG' }; const loc = mockFlowLocation; if (withLocations) { issue.flows = [ [loc(), loc(), loc()], [loc(), loc()] ]; issue.secondaryLocations = [loc(), loc()]; } return { ...issue, ...overrides }; } export function mockLocation(overrides: Partial<Location> = {}): Location { return { action: 'PUSH', hash: '', key: 'key', pathname: '/path', query: {}, search: '', state: {}, ...overrides }; } export function mockMetric( overrides: Partial<Pick<T.Metric, 'key' | 'name' | 'type'>> = {} ): T.Metric { const key = overrides.key || 'coverage'; const name = overrides.name || key[0].toUpperCase() + key.substr(1); const type = overrides.type || 'PERCENT'; return { id: key, key, name, type }; } export function mockMeasure(overrides: Partial<T.Measure> = {}): T.Measure { return { bestValue: true, metric: 'bugs', period: { bestValue: true, index: 1, value: '1.0' }, value: '1.0', ...overrides }; } export function mockMeasureEnhanced(overrides: Partial<T.MeasureEnhanced> = {}): T.MeasureEnhanced { return { bestValue: true, leak: '1', metric: mockMetric({ ...(overrides.metric || {}) }), period: { bestValue: true, index: 1, value: '1.0' }, value: '1.0', ...overrides }; } export function mockOrganization(overrides: Partial<T.Organization> = {}): T.Organization { return { key: 'foo', name: 'Foo', ...overrides }; } export function mockOrganizationWithAdminActions( overrides: Partial<T.Organization> = {}, actionsOverrides: Partial<T.Organization['actions']> = {} ) { return mockOrganization({ actions: { admin: true, ...actionsOverrides }, ...overrides }); } export function mockOrganizationWithAlm( overrides: Partial<T.Organization> = {}, almOverrides: Partial<T.Organization['alm']> = {} ): T.Organization { return mockOrganization({ alm: { key: 'github', membersSync: false, personal: false, url: 'https://github.com/foo', ...almOverrides }, ...overrides }); } export function mockPeriod(overrides: Partial<T.Period> = {}): T.Period { return { date: '2019-04-23T02:12:32+0100', index: 0, mode: 'previous_version', ...overrides }; } export function mockQualityProfile(overrides: Partial<Profile> = {}): Profile { return { activeDeprecatedRuleCount: 2, activeRuleCount: 10, childrenCount: 0, depth: 1, isBuiltIn: false, isDefault: false, isInherited: false, key: 'key', language: 'js', languageName: 'JavaScript', name: 'name', projectCount: 3, organization: 'foo', ...overrides }; } export function mockQualityProfileInheritance( overrides: Partial<T.ProfileInheritanceDetails> = {} ): T.ProfileInheritanceDetails { return { activeRuleCount: 4, isBuiltIn: false, key: 'foo', name: 'Foo', overridingRuleCount: 0, ...overrides }; } export function mockQualityProfileChangelogEvent(eventOverride?: any) { return { action: 'ACTIVATED', date: '2019-04-23T02:12:32+0100', params: { severity: 'MAJOR' }, ruleKey: 'rule-key', ruleName: 'rule-name', ...eventOverride }; } export function mockQualityProfileExporter(override?: Partial<Exporter>): Exporter { return { key: 'exporter-key', name: 'exporter-name', languages: ['first-lang', 'second-lang'], ...override }; } export function mockRouter(overrides: { push?: Function; replace?: Function } = {}) { return { createHref: jest.fn(), createPath: jest.fn(), go: jest.fn(), goBack: jest.fn(), goForward: jest.fn(), isActive: jest.fn(), push: jest.fn(), replace: jest.fn(), setRouteLeaveHook: jest.fn(), ...overrides } as InjectedRouter; } export function mockRule(overrides: Partial<T.Rule> = {}): T.Rule { return { key: 'javascript:S1067', lang: 'js', langName: 'JavaScript', name: 'Use foo', severity: 'MAJOR', status: 'READY', sysTags: ['a', 'b'], tags: ['x'], type: 'CODE_SMELL', ...overrides } as T.Rule; } export function mockRuleDetails(overrides: Partial<T.RuleDetails> = {}): T.RuleDetails { return { key: 'squid:S1337', repo: 'squid', name: '".equals()" should not be used to test the values of "Atomic" classes', createdAt: '2014-12-16T17:26:54+0100', htmlDesc: '', mdDesc: '', severity: 'MAJOR', status: 'READY', isTemplate: false, tags: [], sysTags: ['multi-threading'], lang: 'java', langName: 'Java', params: [], defaultDebtRemFnType: 'CONSTANT_ISSUE', defaultDebtRemFnOffset: '5min', debtOverloaded: false, debtRemFnType: 'CONSTANT_ISSUE', debtRemFnOffset: '5min', defaultRemFnType: 'CONSTANT_ISSUE', defaultRemFnBaseEffort: '5min', remFnType: 'CONSTANT_ISSUE', remFnBaseEffort: '5min', remFnOverloaded: false, scope: 'MAIN', isExternal: false, type: 'BUG', ...overrides }; } export function mockRuleDetailsParameter( overrides: Partial<T.RuleParameter> = {} ): T.RuleParameter { return { defaultValue: '1', htmlDesc: 'description', key: '1', type: 'number', ...overrides }; } export function mockSourceViewerFile( overrides: Partial<T.SourceViewerFile> = {} ): T.SourceViewerFile { return { key: 'foo', measures: { coverage: '85.2', duplicationDensity: '1.0', issues: '12', lines: '56' }, path: 'foo/bar.ts', project: 'my-project', projectName: 'MyProject', q: 'FIL', uuid: 'foo-bar', ...overrides }; } export function mockStandaloneSysInfo(overrides: Partial<any> = {}): T.SysInfoStandalone { const baseInfo = mockBaseSysInfo(overrides); return { ...baseInfo, System: { ...baseInfo.System, 'High Availability': false, 'Server ID': 'asd564-asd54a-5dsfg45' }, Settings: { 'sonar.cluster.enabled': 'true', 'sonar.cluster.node.name': 'server9.example.com' }, 'Web JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 111 }, 'Web Database Connection': { 'Pool Active Connections': 0, 'Pool Max Connections': 60 }, 'Web Logging': { 'Logs Level': 'INFO', 'Logs Dir': '/logs' }, 'Web JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' }, 'Compute Engine Tasks': { Pending: 0, 'In Progress': 0 }, 'Compute Engine JVM State': { 'Max Memory (MB)': 1024, 'Free Memory (MB)': 89 }, 'Compute Engine Database Connection': { 'Pool Initial Size': 0, 'Pool Active Connections': 0 }, 'Compute Engine Logging': { 'Logs Level': 'DEBUG', 'Logs Dir': '/logs' }, 'Compute Engine JVM Properties': { 'file.encoding': 'UTF-8', 'file.separator': '/' }, ...overrides }; } export function mockStore(state: any = {}, reducer = (state: any) => state): Store { return createStore(reducer, state); } export function mockUser(overrides: Partial<T.User> = {}): T.User { return { active: true, local: true, login: 'john.doe', name: 'John Doe', ...overrides }; } export function mockDocumentationMarkdown( overrides: Partial<{ content: string; title: string; key: string }> = {} ): string { const content = overrides.content || ` ## Lorem Ipsum Donec at est elit. In finibus justo ut augue rhoncus, vitae consequat mauris mattis. Nunc ante est, volutpat ac volutpat ac, pharetra in libero. `; const frontMatter = ` --- ${overrides.title ? 'title: ' + overrides.title : ''} ${overrides.key ? 'key: ' + overrides.key : ''} ---`; return `${frontMatter} ${content}`; } export function mockDocumentationEntry( overrides: Partial<DocumentationEntry> = {} ): DocumentationEntry { return { content: 'Lorem ipsum dolor sit amet fredum', relativeName: 'Lorem', navTitle: undefined, text: 'Lorem ipsum dolor sit amet fredum', title: 'Lorem', url: '/lorem/ipsum', ...overrides }; } export function mockLanguage(overrides: Partial<T.Language> = {}): T.Language { return { key: 'css', name: 'CSS', ...overrides }; } export function mockFlowLocation(overrides: Partial<T.FlowLocation> = {}): T.FlowLocation { return { component: 'main.js', textRange: { startLine: 1, startOffset: 1, endLine: 2, endOffset: 2 }, ...overrides }; } export function mockIdentityProvider( overrides: Partial<T.IdentityProvider> = {} ): T.IdentityProvider { return { backgroundColor: '#000000', iconPath: '/path/icon.svg', key: 'github', name: 'Github', ...overrides }; } export function mockRef( overrides: Partial<React.RefObject<Partial<HTMLElement>>> = {} ): React.RefObject<HTMLElement> { return { current: { getBoundingClientRect: jest.fn(), ...overrides.current } } as React.RefObject<HTMLElement>; }