-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DT-1144: Update Support Destination URLs #2768
Changes from 10 commits
089d202
6284f96
98a82cc
19fb0b8
c3a9001
56dd545
620782c
dcebd42
8b8b81a
60227ee
e4ab84c
4e0793d
8db765b
1a147de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* eslint-disable no-undef */ | ||
|
||
import React from 'react'; | ||
import {mount} from 'cypress/react18'; | ||
import {SupportRequestModal} from '../../../src/components/modals/SupportRequestModal'; | ||
import {Storage} from '../../../src/libs/storage'; | ||
|
||
const mockUser = { | ||
displayName: 'Display Name', | ||
email: '[email protected]' | ||
}; | ||
|
||
const handler = () => { | ||
}; | ||
|
||
describe('Support Request Modal Tests', () => { | ||
|
||
beforeEach(() => { | ||
cy.viewport(500, 500); | ||
cy.initApplicationConfig(); | ||
}); | ||
|
||
describe('When a user is logged in:', () => { | ||
beforeEach(() => { | ||
cy.stub(Storage, 'userIsLogged').returns(true); | ||
cy.stub(Storage, 'getCurrentUser').returns(mockUser); | ||
}); | ||
|
||
it('Renders form correctly', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// These fields should exist | ||
cy.get('[data-cy="closeButton"]').should('exist'); | ||
cy.get('[data-cy="supportForm"]').should('exist'); | ||
cy.get('[data-cy="supportFormEmail"]').should('not.exist'); | ||
cy.get('[data-cy="supportFormName"]').should('not.exist'); | ||
cy.get('[data-cy="supportFormType"]').should('exist'); | ||
cy.get('[data-cy="supportFormSubject"]').should('exist'); | ||
cy.get('[data-cy="supportFormDescription"]').should('exist'); | ||
cy.get('[data-cy="supportFormAttachment"]').should('exist'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormCancel"]').should('not.be.disabled'); | ||
}); | ||
|
||
it('Submits properly', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// Ensure that all required fields are filled out before submit becomes available | ||
cy.get('[data-cy="supportFormType"]').select('bug'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormSubject"]').type('Subject'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormDescription"]').type('Description'); | ||
// Form is complete: | ||
cy.get('[data-cy="supportFormSubmit"]').should('not.be.disabled'); | ||
cy.get('[data-cy="supportFormCancel"]').should('not.be.disabled'); | ||
cy.intercept({method: 'POST', url: '**/support/request'}, {statusCode: 201}).as('request'); | ||
cy.intercept({method: 'POST', url: '**/support/upload'}, {statusCode: 201, body: {'token': 'token_string'}}).as('upload'); | ||
// {force: true} is necessary here due to the surrounding div that covers the input. | ||
cy.get('[data-cy="supportFormAttachment"]').selectFile(['cypress/fixtures/example.json'], {force: true}); | ||
cy.get('[data-cy="supportFormSubmit"]').click(); | ||
cy.wait(['@request', '@upload']).then((interceptions) => { | ||
assert(interceptions.length === 2); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
describe('When a user is NOT logged in:', () => { | ||
beforeEach(() => { | ||
cy.stub(Storage, 'userIsLogged').returns(false); | ||
cy.stub(Storage, 'getCurrentUser').returns(undefined); | ||
}); | ||
|
||
it('Renders form correctly', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// These fields should exist | ||
cy.get('[data-cy="closeButton"]').should('exist'); | ||
cy.get('[data-cy="supportForm"]').should('exist'); | ||
cy.get('[data-cy="supportFormEmail"]').should('exist'); | ||
cy.get('[data-cy="supportFormName"]').should('exist'); | ||
cy.get('[data-cy="supportFormType"]').should('exist'); | ||
cy.get('[data-cy="supportFormSubject"]').should('exist'); | ||
cy.get('[data-cy="supportFormDescription"]').should('exist'); | ||
cy.get('[data-cy="supportFormAttachment"]').should('exist'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormCancel"]').should('not.be.disabled'); | ||
}); | ||
|
||
it('Submits properly', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// Ensure that all required fields are filled out before submit becomes available | ||
cy.get('[data-cy="supportFormName"]').type('Name'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormType"]').select('bug'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormSubject"]').type('Subject'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormDescription"]').type('Description'); | ||
cy.get('[data-cy="supportFormSubmit"]').should('be.disabled'); | ||
cy.get('[data-cy="supportFormEmail"]').type(mockUser.email); | ||
// Form is complete: | ||
cy.get('[data-cy="supportFormSubmit"]').should('not.be.disabled'); | ||
cy.get('[data-cy="supportFormCancel"]').should('not.be.disabled'); | ||
cy.intercept({method: 'POST', url: '**/support/request'}, {statusCode: 201}).as('request'); | ||
cy.intercept({method: 'POST', url: '**/support/upload'}, {statusCode: 201, body: {'token': 'token_string'}}).as('upload'); | ||
// {force: true} is necessary here due to the surrounding div that covers the input. | ||
cy.get('[data-cy="supportFormAttachment"]').selectFile(['cypress/fixtures/example.json'], {force: true}); | ||
cy.get('[data-cy="supportFormSubmit"]').click(); | ||
cy.wait(['@request', '@upload']).then((interceptions) => { | ||
assert(interceptions.length === 2); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
describe('File Attachments', () => { | ||
beforeEach(() => { | ||
cy.stub(Storage, 'userIsLogged').returns(false); | ||
cy.stub(Storage, 'getCurrentUser').returns(undefined); | ||
}); | ||
it('Single attachment displayed', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// {force: true} is necessary here due to the surrounding div that covers the input. | ||
cy.get('[data-cy="supportFormAttachment"]').selectFile(['cypress/fixtures/example.json'], {force: true}); | ||
const container = cy.get('[data-cy="supportFormAttachmentContainer"]'); | ||
expect(container.contains('example.json')); | ||
}); | ||
|
||
it('Multiple attachments displayed', () => { | ||
mount(<SupportRequestModal | ||
onCloseRequest={handler} | ||
onOKRequest={handler} | ||
url={'url'} | ||
showModal={true} | ||
/>); | ||
// {force: true} is necessary here due to the surrounding div that covers the input. | ||
cy.get('[data-cy="supportFormAttachment"]').selectFile(['cypress/fixtures/example.json', 'cypress/fixtures/dataset-registration-schema_v1.json'], {force: true}); | ||
const container = cy.get('[data-cy="supportFormAttachmentContainer"]'); | ||
expect(container.contains('2 files selected')); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,36 @@ | ||
import * as fp from 'lodash/fp'; | ||
import { Config } from '../config'; | ||
import { fetchAny } from '../ajax'; | ||
|
||
import {getApiUrl} from '../ajax'; | ||
import axios from 'axios'; | ||
|
||
export const Support = { | ||
createTicket: (name, type, email, subject, description, attachmentToken, url) => { | ||
const ticket = {}; | ||
|
||
ticket.request = { | ||
requester: { name: name, email: email }, | ||
createTicket: (name, type, email, subject, description, attachmentToken, url) => { | ||
return { | ||
name: name, | ||
type: type.toUpperCase(), | ||
email: email, | ||
subject: subject, | ||
// BEWARE changing the following ids or values! If you change them then you must thoroughly test. | ||
custom_fields: [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what was the purpose of these fields? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @raejohanek They are custom field identifiers defined in the Zendesk admin portal that describe the fields displayed in their UI. These were copied over to the API layer here: https://github.com/DataBiosphere/consent/pull/2448/files#diff-310d0997bfbaf3ef54cfda5d6fdd932c172581d9e7e4b38d2a0a44c7f037c91aR48 |
||
{ id: 360012744452, value: type }, | ||
{ id: 360007369412, value: description }, | ||
{ id: 360012744292, value: name }, | ||
{ id: 360012782111, value: email }, | ||
{ id: 360018545031, value: email } | ||
], | ||
comment: { | ||
body: description + '\n\n------------------\nSubmitted from: ' + url, | ||
uploads: attachmentToken | ||
}, | ||
ticket_form_id: 360000669472 | ||
description: description, | ||
url: url, | ||
uploads: attachmentToken | ||
}; | ||
|
||
return ticket; | ||
|
||
}, | ||
|
||
createSupportRequest: async (ticket) => { | ||
const res = await fetchAny('https://broadinstitute.zendesk.com/api/v2/requests.json', fp.mergeAll([Config.jsonBody(ticket), { method: 'POST' }])); | ||
return await res; | ||
const url = `${await getApiUrl()}/support/request`; | ||
return await axios.post(url, ticket, {headers: {'Content-Type': 'application/json'}}).catch( | ||
function (error) { | ||
return Promise.reject(error.response); | ||
} | ||
); | ||
}, | ||
|
||
uploadAttachment: async (file) => { | ||
const res = await fetchAny('https://broadinstitute.zendesk.com/api/v2/uploads?filename=Attachment', fp.mergeAll([Config.attachmentBody(file), { method: 'POST' }])); | ||
return (await res.json()).upload; | ||
const url = `${await getApiUrl()}/support/upload`; | ||
return await axios.post(url, file, {headers: {'Content-Type': 'application/binary'}}).catch( | ||
function (error) { | ||
return Promise.reject(error.response); | ||
} | ||
); | ||
}, | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,8 +17,6 @@ export const Config = { | |
|
||
getNihUrl: async () => (await getConfig()).nihUrl, | ||
|
||
getGoogleClientId: async () => (await getConfig()).clientId, | ||
|
||
Comment on lines
-20
to
-21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drive-by fix: unused method. |
||
getGAId: async () => (await getConfig()).gaId, | ||
|
||
getErrorApiKey: async () => (await getConfig()).errorApiKey, | ||
|
@@ -65,11 +63,6 @@ export const Config = { | |
headers: {'Content-Type': 'application/json'}, | ||
}), | ||
|
||
attachmentBody: body => ({ | ||
body: body, | ||
headers: {'Content-Type': 'application/binary'} | ||
}), | ||
|
||
}; | ||
|
||
export const Token = { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by fix: unused method.