Browse Source

fix(issues) Don't use organization endpoints on project view (#11850)

There are some permissions issues let to solve and using the
organization endpoint on the project view triggers errors.

Fixes APP-1073
Mark Story 6 years ago
parent
commit
d5a8083a92

+ 13 - 5
src/sentry/static/sentry/app/actionCreators/processingIssues.jsx

@@ -1,10 +1,18 @@
 export function fetchProcessingIssues(api, orgId, projectIds = null) {
-  let query = null;
-  if (projectIds) {
-    query = {project: projectIds};
-  }
   return api.requestPromise(`/organizations/${orgId}/processingissues/`, {
     method: 'GET',
-    query,
+    query: projectIds ? {project: projectIds} : null,
   });
 }
+
+export function fetchProjectProcessingIssues(api, orgId, projectId) {
+  // Use the project based endpoint as there is a permissions issue in the backend
+  // and calling the old endpoint is a simple short term solution.
+  return api
+    .requestPromise(`/projects/${orgId}/${projectId}/processingissues/`)
+    .then(data => {
+      // Normalize data to match what the organization endpoint would return
+      data.project = projectId;
+      return [data];
+    });
+}

+ 16 - 6
src/sentry/static/sentry/app/components/stream/processingIssueList.jsx

@@ -4,13 +4,17 @@ import PropTypes from 'prop-types';
 
 import {Client} from 'app/api';
 import {logAjaxError} from 'app/utils/logging';
-import {fetchProcessingIssues} from 'app/actionCreators/processingIssues';
+import {
+  fetchProcessingIssues,
+  fetchProjectProcessingIssues,
+} from 'app/actionCreators/processingIssues';
 import ProcessingIssueHint from 'app/components/stream/processingIssueHint';
 import SentryTypes from 'app/sentryTypes';
 
 class ProcessingIssueList extends React.Component {
   static propTypes = {
     organization: SentryTypes.Organization.isRequired,
+    project: SentryTypes.Project,
     projectIds: PropTypes.array,
     showProject: PropTypes.bool,
   };
@@ -43,11 +47,17 @@ class ProcessingIssueList extends React.Component {
   }
 
   fetchIssues() {
-    let {organization, projectIds} = this.props;
+    const {organization, project, projectIds} = this.props;
+    let promise;
+    if (project) {
+      promise = fetchProjectProcessingIssues(this.api, organization.slug, project.slug);
+    } else {
+      promise = fetchProcessingIssues(this.api, organization.slug, projectIds);
+    }
 
-    fetchProcessingIssues(this.api, organization.slug, projectIds).then(
+    promise.then(
       data => {
-        let hasIssues = data.some(
+        const hasIssues = data.some(
           p => p.hasIssues || p.resolveableIssues > 0 || p.issuesProcessing > 0
         );
 
@@ -63,8 +73,8 @@ class ProcessingIssueList extends React.Component {
   }
 
   render() {
-    let {issues} = this.state;
-    let {organization, showProject} = this.props;
+    const {issues} = this.state;
+    const {organization, showProject} = this.props;
 
     return (
       <React.Fragment>

+ 0 - 4
src/sentry/static/sentry/app/views/organizationStream/overview.jsx

@@ -309,10 +309,6 @@ const OrganizationStream = createReactClass({
     });
   },
 
-  showingProcessingIssues() {
-    return this.state.query && this.state.query.trim() == 'is:unprocessed';
-  },
-
   resumePolling() {
     if (!this.state.pageLinks) return;
 

+ 1 - 8
src/sentry/static/sentry/app/views/stream/stream.jsx

@@ -228,10 +228,6 @@ const Stream = createReactClass({
     );
   },
 
-  showingProcessingIssues() {
-    return this.state.query && this.state.query.trim() == 'is:unprocessed';
-  },
-
   onSavedSearchCreate(data) {
     let savedSearchList = this.state.savedSearchList;
     savedSearchList.push(data);
@@ -695,10 +691,7 @@ const Stream = createReactClass({
               allResultsVisible={this.allResultsVisible()}
             />
             <PanelBody>
-              <ProcessingIssueList
-                organization={organization}
-                projectIds={[project.id]}
-              />
+              <ProcessingIssueList organization={organization} project={project} />
               {this.renderStreamBody()}
             </PanelBody>
           </Panel>

+ 28 - 0
tests/js/spec/components/stream/processingIssueList.spec.jsx

@@ -45,6 +45,34 @@ describe('ProcessingIssueList', function() {
     });
   });
 
+  describe('componentDidMount project prop', function() {
+    let instance, fetchRequest, project;
+
+    beforeEach(async function() {
+      fetchRequest = MockApiClient.addMockResponse({
+        url: '/projects/org-slug/project-slug/processingissues/',
+        method: 'GET',
+        body: {
+          numIssues: 1,
+          hasIssues: true,
+          lastSeen: '2019-01-16T15:39:11.081Z',
+        },
+      });
+      project = TestStubs.Project();
+      wrapper = shallow(
+        <ProcessingIssueList organization={organization} project={project} />
+      );
+      instance = wrapper.instance();
+      await instance.componentDidMount();
+    });
+
+    it('fetches issues', function() {
+      expect(instance.state.issues).toBeTruthy();
+      expect(instance.state.issues[0].project).toEqual(project.slug);
+      expect(fetchRequest).toHaveBeenCalled();
+    });
+  });
+
   describe('render', function() {
     beforeEach(async function() {
       wrapper = shallow(

+ 74 - 8
tests/js/spec/views/stream/__snapshots__/stream.spec.jsx.snap

@@ -96,10 +96,43 @@ exports[`Stream render() displays the group list 1`] = `
               "teams": Array [],
             }
           }
-          projectIds={
-            Array [
-              "3559",
-            ]
+          project={
+            Object {
+              "allowedDomains": Array [
+                "example.com",
+                "https://example.com",
+              ],
+              "dataScrubber": false,
+              "dataScrubberDefaults": false,
+              "digestsMaxDelay": 60,
+              "digestsMinDelay": 5,
+              "features": Array [],
+              "firstEvent": true,
+              "hasAccess": true,
+              "id": "3559",
+              "isBookmarked": false,
+              "isMember": true,
+              "name": "Foo Project",
+              "resolveAge": 48,
+              "safeFields": Array [
+                "business-email",
+                "company",
+              ],
+              "scrapeJavaScript": true,
+              "scrubIPAddresses": false,
+              "securityToken": "security-token",
+              "securityTokenHeader": "x-security-header",
+              "sensitiveFields": Array [
+                "creditcard",
+                "ssn",
+              ],
+              "slug": "project-slug",
+              "storeCrashReports": false,
+              "subjectPrefix": "[my-org]",
+              "subjectTemplate": "[$project] \${tag:level}: $title",
+              "teams": Array [],
+              "verifySSL": true,
+            }
           }
           showProject={false}
         />
@@ -305,10 +338,43 @@ exports[`Stream toggles environment select all environments 1`] = `
               "teams": Array [],
             }
           }
-          projectIds={
-            Array [
-              "3559",
-            ]
+          project={
+            Object {
+              "allowedDomains": Array [
+                "example.com",
+                "https://example.com",
+              ],
+              "dataScrubber": false,
+              "dataScrubberDefaults": false,
+              "digestsMaxDelay": 60,
+              "digestsMinDelay": 5,
+              "features": Array [],
+              "firstEvent": true,
+              "hasAccess": true,
+              "id": "3559",
+              "isBookmarked": false,
+              "isMember": true,
+              "name": "Foo Project",
+              "resolveAge": 48,
+              "safeFields": Array [
+                "business-email",
+                "company",
+              ],
+              "scrapeJavaScript": true,
+              "scrubIPAddresses": false,
+              "securityToken": "security-token",
+              "securityTokenHeader": "x-security-header",
+              "sensitiveFields": Array [
+                "creditcard",
+                "ssn",
+              ],
+              "slug": "project-slug",
+              "storeCrashReports": false,
+              "subjectPrefix": "[my-org]",
+              "subjectTemplate": "[$project] \${tag:level}: $title",
+              "teams": Array [],
+              "verifySSL": true,
+            }
           }
           showProject={false}
         />