useMetricsContext.spec.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen} from 'sentry-test/reactTestingLibrary';
  3. import {Organization} from 'sentry/types';
  4. import {MetricsProvider} from 'sentry/utils/metrics/metricsProvider';
  5. import {useMetricsContext} from 'sentry/utils/useMetricsContext';
  6. function mockMetricsAndTags(orgSlug: Organization['slug']) {
  7. const tagsMock = MockApiClient.addMockResponse({
  8. url: `/organizations/${orgSlug}/metrics/tags/`,
  9. body: [{key: 'environment'}, {key: 'release'}, {key: 'session.status'}],
  10. });
  11. const metasMock = MockApiClient.addMockResponse({
  12. url: `/organizations/${orgSlug}/metrics/meta/`,
  13. body: [
  14. {
  15. name: 'sentry.sessions.session',
  16. type: 'counter',
  17. operations: ['sum'],
  18. },
  19. {
  20. name: 'sentry.sessions.session.error',
  21. type: 'set',
  22. operations: ['count_unique'],
  23. },
  24. ],
  25. });
  26. return {tagsMock, metasMock};
  27. }
  28. function TestComponent({other}: {other: string}) {
  29. const {tags, metas} = useMetricsContext();
  30. return (
  31. <div>
  32. <span>{other}</span>
  33. {tags && Object.entries(tags).map(([key, tag]) => <em key={key}>{tag.key}</em>)}
  34. {metas &&
  35. Object.entries(metas).map(([key, meta]) => <em key={key}>{meta.name}</em>)}
  36. </div>
  37. );
  38. }
  39. describe('useMetricsContext', function () {
  40. const {organization, project} = initializeOrg();
  41. it("fetches metrics and tags and save values in the context's state", async function () {
  42. const {tagsMock, metasMock} = mockMetricsAndTags(organization.slug);
  43. render(
  44. <MetricsProvider organization={organization} projects={[project.id]}>
  45. <TestComponent other="value" />
  46. </MetricsProvider>
  47. );
  48. // Should forward prop
  49. expect(screen.getByText('value')).toBeInTheDocument();
  50. expect(tagsMock).toHaveBeenCalledTimes(1);
  51. expect(metasMock).toHaveBeenCalledTimes(1);
  52. // includes metric tags
  53. expect(await screen.findByText('session.status')).toBeInTheDocument();
  54. // include metric metas
  55. expect(screen.getByText('sentry.sessions.session')).toBeInTheDocument();
  56. expect(screen.getByText('sentry.sessions.session.error')).toBeInTheDocument();
  57. });
  58. it('skip metrics and tags fetches', function () {
  59. const {tagsMock, metasMock} = mockMetricsAndTags(organization.slug);
  60. render(
  61. <MetricsProvider organization={organization} projects={[project.id]} skipLoad>
  62. <TestComponent other="value" />
  63. </MetricsProvider>
  64. );
  65. // Should forward prop
  66. expect(screen.getByText('value')).toBeInTheDocument();
  67. expect(tagsMock).not.toHaveBeenCalled();
  68. expect(metasMock).not.toHaveBeenCalled();
  69. // does not include metrics tags
  70. expect(screen.queryByText('session.status')).not.toBeInTheDocument();
  71. // does not include metrics metas
  72. expect(screen.queryByText('sentry.sessions.session')).not.toBeInTheDocument();
  73. expect(screen.queryByText('sentry.sessions.session.error')).not.toBeInTheDocument();
  74. });
  75. it('throw when provider is not set', function () {
  76. try {
  77. render(<TestComponent other="value" />);
  78. } catch (error) {
  79. expect(error.message).toEqual(
  80. 'useMetricsContext was called outside of MetricsProvider'
  81. );
  82. }
  83. });
  84. });