123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
- import {SlowestFunctionsTable} from 'sentry/views/profiling/landing/slowestFunctionsTable';
- describe('SlowestFunctionsTable', () => {
- it('shows loading state', () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- body: [],
- });
- render(<SlowestFunctionsTable />);
- expect(screen.getByTestId('loading-indicator')).toBeInTheDocument();
- });
- it('shows error state', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- body: [],
- statusCode: 500,
- });
- render(<SlowestFunctionsTable />);
- expect(await screen.findByTestId('error-indicator')).toBeInTheDocument();
- });
- it('shows no functions state', async () => {
- // @ts-expect-error partial schema mock
- const schema: Profiling.Schema = {
- metrics: [],
- };
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- match: [
- MockApiClient.matchQuery({
- expand: 'metrics',
- }),
- ],
- body: schema,
- });
- render(<SlowestFunctionsTable />);
- expect(await screen.findByText('No functions found')).toBeInTheDocument();
- });
- it('renders function fields', async () => {
- // @ts-expect-error partial schema mock
- const schema: Profiling.Schema = {
- metrics: [
- {
- name: 'slow-function',
- package: 'slow-package',
- p75: 1500 * 1e6,
- p95: 2000 * 1e6,
- p99: 3000 * 1e6,
- sum: 60_000 * 1e6,
- count: 5000,
- avg: 0.5 * 1e6,
- in_app: true,
- fingerprint: 12345,
- examples: [
- {
- project_id: 1,
- profile_id: 'profile-id',
- },
- ],
- },
- ],
- };
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- match: [
- MockApiClient.matchQuery({
- expand: 'metrics',
- }),
- ],
- body: schema,
- });
- render(<SlowestFunctionsTable />);
- for (const value of ['slow-function', 'slow-package', '1.50s', '2.00s', '3.00s']) {
- expect(await screen.findByText(value)).toBeInTheDocument();
- }
- });
- it('paginates response', async () => {
- // @ts-expect-error partial schema mock
- const schema: Profiling.Schema = {
- metrics: [],
- };
- for (let i = 0; i < 10; i++) {
- schema.metrics?.push({
- name: 'slow-function',
- package: 'slow-package',
- p75: 1500 * 1e6,
- p95: 2000 * 1e6,
- p99: 3000 * 1e6,
- sum: 60_000 * 1e6,
- count: 5000,
- avg: 0.5 * 1e6,
- in_app: true,
- fingerprint: 12345,
- examples: [
- {
- project_id: 1,
- profile_id: 'profile-id',
- },
- ],
- });
- }
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- match: [
- MockApiClient.matchQuery({
- expand: 'metrics',
- }),
- ],
- body: schema,
- });
- render(<SlowestFunctionsTable />);
- expect(await screen.findAllByText('slow-function')).toHaveLength(5);
- });
- it('paginates results', async () => {
- // @ts-expect-error partial schema mock
- const schema: Profiling.Schema = {
- metrics: [],
- };
- for (let i = 0; i < 10; i++) {
- schema.metrics?.push({
- name: 'slow-function-' + i,
- package: 'slow-package',
- p75: 1500 * 1e6,
- p95: 2000 * 1e6,
- p99: 3000 * 1e6,
- sum: 60_000 * 1e6,
- count: 5000,
- avg: 0.5 * 1e6,
- in_app: true,
- fingerprint: 12345,
- examples: [
- {
- project_id: 1,
- profile_id: 'profile-id',
- },
- ],
- });
- }
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- match: [
- MockApiClient.matchQuery({
- expand: 'metrics',
- }),
- ],
- body: schema,
- });
- render(<SlowestFunctionsTable />);
- expect(await screen.findAllByText('slow-package')).toHaveLength(5);
- await userEvent.click(screen.getByLabelText('Next'));
- for (let i = 6; i < 10; i++) {
- expect(await screen.findByText('slow-function-' + i)).toBeInTheDocument();
- }
- expect(screen.getByLabelText('Next')).toBeDisabled();
- await userEvent.click(screen.getByLabelText('Previous'));
- for (let i = 0; i < 5; i++) {
- expect(await screen.findByText('slow-function-' + i)).toBeInTheDocument();
- }
- expect(screen.getByLabelText('Previous')).toBeDisabled();
- });
- it('fetches function metrics', async () => {
- // @ts-expect-error partial schema mock
- const schema: Profiling.Schema = {
- metrics: [],
- };
- for (let i = 0; i < 10; i++) {
- schema.metrics?.push({
- name: 'slow-function-' + i,
- package: 'slow-package',
- p75: 1500 * 1e6,
- p95: 2000 * 1e6,
- p99: 3000 * 1e6,
- sum: 60_000 * 1e6,
- count: 5000,
- avg: 0.5 * 1e6,
- in_app: true,
- fingerprint: 12345,
- examples: [
- {
- project_id: 1,
- profile_id: 'profile-id',
- },
- ],
- });
- }
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/profiling/flamegraph/',
- match: [
- MockApiClient.matchQuery({
- expand: 'metrics',
- }),
- ],
- body: schema,
- });
- const functionMetricsRequest = MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events-stats/',
- match: [
- MockApiClient.matchQuery({
- query: 'fingerprint:12345',
- dataset: 'profileFunctionsMetrics',
- }),
- ],
- body: [],
- });
- render(<SlowestFunctionsTable />);
- const expandButtons = await screen.findAllByLabelText('View Function Metrics');
- expect(expandButtons).toHaveLength(5);
- await userEvent.click(expandButtons[0]);
- await waitFor(() => {
- expect(functionMetricsRequest).toHaveBeenCalled();
- });
- });
- });
|