Skip to content

Commit c330917

Browse files
authored
fix(analytics): port over the contextual analytics spec (#216)
1 parent eeb75ce commit c330917

File tree

4 files changed

+184
-4
lines changed

4 files changed

+184
-4
lines changed

cypress/e2e/fixtures/consts.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,8 @@ const defaultContext: PortalContext = {
9090
allowed_time_period: '2022-03-25T13:15:02.104Z'
9191
}
9292

93-
export { versions, product, productVersion, productRegistration, apps, defaultContext }
93+
const productRegistrations: GetRegistrationResponse[] = [
94+
productRegistration
95+
]
96+
97+
export { versions, product, productVersion, productRegistration, productRegistrations, apps, defaultContext }
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { apps, productRegistration, productRegistrations, versions } from '../fixtures/consts'
2+
3+
describe('Contextual Developer Analytics', () => {
4+
beforeEach(() => {
5+
cy.mockPrivatePortal()
6+
cy.mockApplications(apps, 4)
7+
cy.intercept('POST', '**/api/v2/stats*', {
8+
statusCode: 200,
9+
body: {
10+
records: []
11+
},
12+
delay: 0
13+
})
14+
})
15+
16+
const selectors = {
17+
chartsParent: '[data-testid="analytics-charts"]',
18+
dashboardDropdownLink: '[data-testid="dropdown-analytics-dashboard"]',
19+
dateTimePicker: '[data-testid="analytics-timepicker"]',
20+
metricCardsParent: '[data-testid="analytics-metric-cards"]',
21+
viewAnalyticsButton: '[data-testid="application-dashboard-button"]'
22+
}
23+
24+
it('My Apps – displays displays metric cards if the feature flag is on', () => {
25+
cy.mockLaunchDarklyFlags([{ name: 'ma-1002-dev-portal-contextual-analytics', value: true }])
26+
27+
cy.mockApplications(apps, 4)
28+
29+
cy.visit('/', { useOriginalFn: true })
30+
cy.visit('/my-apps')
31+
32+
cy.get(selectors.metricCardsParent).should('exist')
33+
cy.get(selectors.metricCardsParent).find('.metricscard').should('have.length', 3)
34+
35+
cy.get('[data-testid="applications-table"]').find('.actions-badge').first().click()
36+
cy.get(selectors.dashboardDropdownLink).should('exist')
37+
})
38+
39+
it('My Apps – does not display metric cards or the analytics dropdown link if the feature flag is off', () => {
40+
cy.mockLaunchDarklyFlags([{ name: 'ma-1002-dev-portal-contextual-analytics', value: false }])
41+
42+
cy.mockApplications(apps, 5)
43+
cy.visit('/my-apps')
44+
45+
cy.get(selectors.metricCardsParent).should('not.exist')
46+
cy.get('[data-testid="applications-table"]').find('.actions-badge').first().click()
47+
cy.get(selectors.dashboardDropdownLink).should('not.exist')
48+
})
49+
50+
it('My App details page – does not display Metrics Card, View Analytics button if the feature flag is off', () => {
51+
cy.mockLaunchDarklyFlags([{ name: 'ma-1002-dev-portal-contextual-analytics', value: true }])
52+
cy.mockApplications(apps, 4)
53+
54+
cy.intercept(
55+
'GET',
56+
`**/api/v2/applications/${apps[0].id}`, {
57+
statusCode: 200,
58+
body: { ...apps[0] }
59+
}
60+
).as('getSingleApplication')
61+
62+
cy.mockApplicationWithCredAndReg(apps[0])
63+
64+
cy.visit(`/application/${apps[0].id}`)
65+
cy.get('[data-testid="analytics-metric-cards"]').should('not.exist')
66+
cy.get('[data-testid="application-dashboard-button"]').should('not.exist')
67+
})
68+
69+
it('App Dashboard - vitals elements load when contextual analytics feature flag is on', () => {
70+
cy.mockLaunchDarklyFlags([{ name: 'ma-1002-dev-portal-contextual-analytics', value: true }])
71+
cy.mockApplications(apps, 4)
72+
73+
cy.intercept('GET', `**/api/v2/applications/${apps[0].id}`, {
74+
statusCode: 200,
75+
body: apps[0],
76+
delay: 0
77+
}).as('getSingleApplication')
78+
79+
cy.intercept(
80+
'GET',
81+
`**/api/v2/applications/${apps[0].id}/registrations*`,
82+
{
83+
body: {
84+
data: productRegistrations,
85+
meta: {
86+
page: {
87+
total: 1,
88+
number: 1,
89+
size: 1
90+
}
91+
}
92+
},
93+
delay: 0
94+
}
95+
).as('getApplicationRegistration')
96+
97+
cy.visit('/my-apps')
98+
99+
// Navigate to Application Dashboard page
100+
cy.get('[data-testid="applications-table"]').find('.actions-badge').first().click()
101+
cy.get(selectors.dashboardDropdownLink).first().click()
102+
103+
// All application dashboard elements should be present
104+
cy.get('.analytics-filters').should('exist')
105+
cy.get(selectors.metricCardsParent).should('exist')
106+
cy.get(selectors.chartsParent).should('exist')
107+
108+
// Check that the Service Versions filter bar contains at least one item
109+
const mockedServiceVersionName = `${productRegistrations[0].product_name} - ${productRegistrations[0].product_version_name}`
110+
111+
cy.get('[data-testid="k-multiselect-input"]').should('exist').click()
112+
cy.get('.k-multiselect-item').first().should('contain', mockedServiceVersionName)
113+
})
114+
})

cypress/e2e/support/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-console */
22
// Import commands.js using ES2015 syntax:
3-
import { GetApplicationResponse, GetRegistrationResponse, PortalAppearance, PortalContext, Product, ProductCatalogIndexSource, ProductVersion, ProductVersionSpecOperationsOperationsInner } from '@kong/sdk-portal-js'
3+
import { GetApplicationResponse, GetRegistrationResponse, ListCredentialsResponseDataInner, PortalAppearance, PortalContext, Product, ProductCatalogIndexSource, ProductVersion, ProductVersionSpecOperationsOperationsInner } from '@kong/sdk-portal-js'
44
import './mock-commands'
55
import { SinonStub } from 'cypress/types/sinon'
66

@@ -25,6 +25,7 @@ declare global {
2525
mockProductApiDocument(productId?: string, options?: Partial<TypeOptions> & {body: any}): Chainable<JQuery<HTMLElement>>
2626
mockProduct(productId?: string, mockProduct?: Product, mockVersions?: ProductVersion[]): Chainable<JQuery<HTMLElement>>
2727
mockApplications(searchResults?: Array<GetApplicationResponse>, totalCount?: number, pageSize?: number, pageNumber?: number): Chainable<JQuery<HTMLElement>>
28+
mockApplicationWithCredAndReg(data: GetApplicationResponse, credentials?: ListCredentialsResponseDataInner[], registrations?: Array<GetRegistrationResponse>): Chainable<JQuery<HTMLElement>>,
2829
mockContextualAnalytics(): Chainable<JQuery<HTMLElement>>
2930
mockRegistrations(applicationId?: string, registrations?: Array<GetRegistrationResponse>, totalCount?: number): Chainable<JQuery<HTMLElement>>
3031
mockProductVersionApplicationRegistration(value:any): Chainable<JQuery<HTMLElement>>

cypress/e2e/support/mock-commands.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,23 @@ import document from '../fixtures/dochub_mocks/document.json'
77
import documentTreeJson from '../fixtures/dochub_mocks/documentTree.json'
88
import apiDocumentationJson from '../fixtures/dochub_mocks/parentApiDocumentation.json'
99
import petstoreOperationsV2 from '../fixtures/v2/petstoreOperations.json'
10-
import { ListApplicationsResponse, ListDocumentsTree, PortalAppearance, PortalContext, Product, ProductDocument, ProductDocumentRaw, ProductVersionListPage, ProductVersionSpec, ProductVersionSpecOperations, ProductVersionSpecOperationsOperationsInner, SearchResults } from '@kong/sdk-portal-js'
10+
import {
11+
GetApplicationResponse,
12+
ListApplicationsResponse,
13+
ListCredentialsResponse,
14+
ListDocumentsTree,
15+
ListRegistrationsResponse,
16+
PortalAppearance,
17+
PortalContext,
18+
Product,
19+
ProductDocument,
20+
ProductDocumentRaw,
21+
ProductVersionListPage,
22+
ProductVersionSpecDocument,
23+
ProductVersionSpecOperations,
24+
ProductVersionSpecOperationsOperationsInner,
25+
SearchResults
26+
} from '@kong/sdk-portal-js'
1127
import { THEMES } from '../fixtures/theme.constant'
1228

1329
Cypress.Commands.add('mockStylesheetCss', (theme = 'mint_rocket', fonts = {
@@ -331,6 +347,51 @@ Cypress.Commands.add('mockRegistrations', (applicationId = '*', registrations =
331347
}).as('getRegistrations')
332348
})
333349

350+
Cypress.Commands.add('mockApplicationWithCredAndReg', (
351+
data: GetApplicationResponse,
352+
credentials = [],
353+
registrations = []
354+
) => {
355+
const applicationResponse: GetApplicationResponse = data
356+
357+
cy.intercept('GET', `**/api/v2/applications/${data.id}`, {
358+
statusCode: 200,
359+
body: applicationResponse
360+
}).as('getApplication')
361+
362+
const credsResponse: ListCredentialsResponse = {
363+
data: credentials,
364+
meta: {
365+
page: {
366+
total: credentials.length,
367+
size: 10,
368+
number: 1
369+
}
370+
}
371+
}
372+
373+
cy.intercept('GET', `**/api/v2/applications/${data.id}/credentials*`, {
374+
statusCode: 200,
375+
body: credsResponse
376+
}).as('getApplicationCredentials')
377+
378+
const registrationsResponse: ListRegistrationsResponse = {
379+
data: registrations,
380+
meta: {
381+
page: {
382+
total: registrations.length,
383+
size: 10,
384+
number: 1
385+
}
386+
}
387+
}
388+
389+
cy.intercept('GET', `**/api/v2/applications/${data.id}/registrations*`, {
390+
statusCode: 200,
391+
body: registrationsResponse
392+
}).as('getApplicationRegistrations')
393+
})
394+
334395
Cypress.Commands.add('mockContextualAnalytics', () => {
335396
return cy.intercept(
336397
'POST', '**/api/v2/stats', {
@@ -445,7 +506,7 @@ Cypress.Commands.add('mockGetProductDocumentTree', (productId) => {
445506
})
446507

447508
Cypress.Commands.add('mockProductVersionSpec', (productId = '*', versionId = '*', content = JSON.stringify(petstoreJson30)) => {
448-
const specResponse: ProductVersionSpec = {
509+
const specResponse: ProductVersionSpecDocument = {
449510
api_type: 'openapi',
450511
content
451512
}

0 commit comments

Comments
 (0)