Skip to content

Commit c620679

Browse files
committed
feat: update sendfeedback api and add testcase
1 parent e4fdc92 commit c620679

File tree

7 files changed

+101
-23
lines changed

7 files changed

+101
-23
lines changed

docs/useCases.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ _See [use case](../src/info/domain/useCases/GetZipDownloadLimit.ts) implementati
13701370

13711371
#### Send Feedback to Object Contacts
13721372

1373-
Returns a [Contact](../src/contactInfo/domain/models/Contact.ts) object, which contains contact return information, showing toEmail, fromEmail, subject, body.
1373+
Returns a [Contact](../src/contactInfo/domain/models/Contact.ts) object, which contains contact return information, showing fromEmail, subject, body.
13741374

13751375
##### Example call:
13761376

@@ -1379,9 +1379,25 @@ import { submitContactInfo } from '@iqss/dataverse-client-javascript'
13791379

13801380
/* ... */
13811381

1382-
submitContactInfo.execute((contact: ContactDTO)).then( => {
1383-
/* ... */
1384-
})
1382+
const contactDTO: ContactDTO = {
1383+
targedId: 1
1384+
subject: 'Data Question',
1385+
body: 'Please help me understand your data. Thank you!',
1386+
fromEmail: '[email protected]'
1387+
}
1388+
1389+
submitContactInfo.execute(contactDTO)
13851390

13861391
/* ... */
13871392
```
1393+
1394+
_See [use case](../src/info/domain/useCases/submitContactInfo.ts) implementation_.
1395+
1396+
The above example would submit feedback to all contacts of a object where the object targetId = 1.
1397+
1398+
In ContactDTO, it takes the following information:
1399+
1400+
- **targetId**: the numeric identifier of the collection, dataset, or datafile. Persistent ids and collection aliases are not supported. (Optional)
1401+
- **subject**: the email subject line
1402+
- **body**: the email body to send
1403+
- **fromEmail**: the email to list in the reply-to field.

src/contactInfo/domain/dtos/ContactDTO.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export interface ContactDTO {
2-
targetId: number
2+
targetId?: number
33
subject: string
44
body: string
55
fromEmail: string
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export interface Contact {
22
fromEmail: string
3-
toEmail: string
43
body: string
54
subject: string
65
}

src/contactInfo/infra/repositories/ContactRepository.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ import { ContactDTO } from '../../domain/dtos/ContactDTO'
55

66
export class ContactRepository extends ApiRepository implements IContactRepository {
77
public async submitContactInfo(contactDTO: ContactDTO): Promise<Contact[]> {
8-
return this.doPost(`/admin/feedback`, contactDTO)
8+
return this.doPost(`/sendfeedback`, contactDTO)
99
.then((response) => {
1010
const responseData = response.data
1111
const contact: Contact[] = responseData.data.map((item: Contact) => ({
1212
fromEmail: item.fromEmail,
13-
toEmail: item.toEmail,
1413
subject: item.subject,
1514
body: item.body
1615
}))

test/functional/contact/SubmitContactInfo.test.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ApiConfig, submitContactInfo, ContactDTO, WriteError } from '../../../src'
1+
import { ApiConfig, submitContactInfo, ContactDTO, WriteError, Contact } from '../../../src'
22
import { TestConstants } from '../../testHelpers/TestConstants'
33
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
44

@@ -11,25 +11,44 @@ describe('submitContactInfo', () => {
1111
)
1212
})
1313

14-
test('should return success result on repository success', async () => {
14+
test('should return Contact result successfully', async () => {
1515
const contactDTO: ContactDTO = {
1616
targetId: 1,
1717
subject: 'Data Question',
1818
body: 'Please help me understand your data. Thank you!',
19-
fromEmail: '1314@gmail.com'
19+
fromEmail: 'example@gmail.com'
2020
}
2121

22-
let contactInfo
22+
let contactInfo: Contact[] = []
2323
try {
2424
contactInfo = await submitContactInfo.execute(contactDTO)
2525
} catch (error) {
2626
throw new Error('Contact info should be submitted')
2727
} finally {
2828
expect(contactInfo).toBeDefined()
29-
expect(contactInfo[0].fromEmail).toEqual('[email protected]')
29+
expect(contactInfo[0].fromEmail).toEqual('[email protected]')
30+
expect(contactInfo[0].subject).toEqual(expect.any(String))
31+
expect(contactInfo[0].body).toEqual(expect.any(String))
32+
}
33+
})
34+
35+
test('should return a Contact when targetId is not provided', async () => {
36+
const contactDTO: ContactDTO = {
37+
subject: 'General Inquiry',
38+
body: 'I have a general question.',
39+
fromEmail: '[email protected]'
40+
}
41+
42+
let contactInfo: Contact[] = []
43+
try {
44+
contactInfo = await submitContactInfo.execute(contactDTO)
45+
} catch (error) {
46+
throw new Error('Contact info should be submitted even if target id is missing')
47+
} finally {
48+
expect(contactInfo).toBeDefined()
49+
expect(contactInfo[0].fromEmail).toEqual('[email protected]')
3050
expect(contactInfo[0].subject).toEqual(expect.any(String))
3151
expect(contactInfo[0].body).toEqual(expect.any(String))
32-
expect(contactInfo[0].toEmail).toEqual(expect.any(String))
3352
}
3453
})
3554

@@ -38,7 +57,7 @@ describe('submitContactInfo', () => {
3857
targetId: 0,
3958
subject: '',
4059
body: '',
41-
fromEmail: '1314@gmail.com'
60+
fromEmail: 'example@gmail.com'
4261
}
4362
const expectedError = new WriteError(`[400] Feedback target object not found`)
4463
await expect(submitContactInfo.execute(contactDTO)).rejects.toThrow(expectedError)

test/integration/contact/ContactRepository.test.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ContactRepository } from '../../../src/contactInfo/infra/repositories/ContactRepository'
2-
import { ApiConfig, ContactDTO, WriteError } from '../../../src'
2+
import { ApiConfig, Contact, ContactDTO, WriteError } from '../../../src'
33
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
44
import { TestConstants } from '../../testHelpers/TestConstants'
55

@@ -16,7 +16,7 @@ describe('submitContactInfo', () => {
1616
targetId: 1,
1717
subject: 'Data Question',
1818
body: 'Please help me understand your data. Thank you!',
19-
fromEmail: '1314@gmail.com'
19+
fromEmail: 'example@gmail.com'
2020
}
2121

2222
const sut: ContactRepository = new ContactRepository()
@@ -28,7 +28,23 @@ describe('submitContactInfo', () => {
2828
expect(contactInfo[0].fromEmail).toEqual(testContactDTO.fromEmail)
2929
expect(contactInfo[0].subject).toEqual(expect.any(String))
3030
expect(contactInfo[0].body).toEqual(expect.any(String))
31-
expect(contactInfo[0].toEmail).toEqual(expect.any(String))
31+
})
32+
33+
test('should return a Contact when targetId is not provided', async () => {
34+
const contactDTOWithoutTargetId: Partial<ContactDTO> = {
35+
subject: 'General Inquiry',
36+
body: 'I have a general question.',
37+
fromEmail: '[email protected]'
38+
}
39+
40+
const contactInfo: Contact[] = await sut.submitContactInfo(
41+
contactDTOWithoutTargetId as ContactDTO
42+
)
43+
44+
expect(contactInfo).toBeDefined()
45+
expect(contactInfo[0].fromEmail).toEqual(contactDTOWithoutTargetId.fromEmail)
46+
expect(contactInfo[0].subject).toEqual(expect.any(String))
47+
expect(contactInfo[0].body).toEqual(expect.any(String))
3248
})
3349

3450
test('should return error if the target id is unexisted', async () => {

test/unit/contact/SubmitContactInfo.test.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { WriteError, Contact, ContactDTO } from '../../../src'
22
import { SubmitContactInfo } from '../../../src/contactInfo/domain/useCases/SubmitContactInfo'
33
import { IContactRepository } from '../../../src/contactInfo/domain/repositories/IContactRepository'
4+
import { TestConstants } from '../../testHelpers/TestConstants'
45

56
describe('execute submit information to contacts', () => {
67
test('should return a Contact when repository call is successful', async () => {
7-
const fromEmail = '1314@gmail.com'
8+
const fromEmail = 'example@gmail.com'
89

910
const contactDTO: ContactDTO = {
1011
targetId: 6,
@@ -14,8 +15,7 @@ describe('execute submit information to contacts', () => {
1415
}
1516

1617
const collectionAlias = 'collection-1'
17-
const collectionEmail = '[email protected],[email protected]'
18-
const baseUrl = 'http://localhost:8080/dataverse/'
18+
const baseUrl = TestConstants.TEST_API_URL + '/dataverse/'
1919
const bodyMessage =
2020
'You have just been sent the following message from ' +
2121
fromEmail +
@@ -42,7 +42,6 @@ describe('execute submit information to contacts', () => {
4242
const expectedResponse: Contact[] = [
4343
{
4444
fromEmail: contactDTO.fromEmail,
45-
toEmail: collectionEmail,
4645
subject: 'Root contact: ' + contactDTO.subject,
4746
body: bodyMessage
4847
}
@@ -57,7 +56,37 @@ describe('execute submit information to contacts', () => {
5756
expect(contactRepositoryStub.submitContactInfo).toHaveBeenCalledWith(contactDTO)
5857
})
5958

60-
test('should return error result on error response', async () => {
59+
test('should return a Contact when targetId is not provided', async () => {
60+
const fromEmail = '[email protected]'
61+
62+
const contactDTO: ContactDTO = {
63+
subject: 'Data Question',
64+
body: 'Please help me understand your data. Thank you!',
65+
fromEmail: fromEmail
66+
}
67+
68+
const bodyMessage =
69+
'Root Support,\n\nThe following message was sent from ' +
70+
fromEmail +
71+
'.\n\n---\n\nPlease help me understand your data. Thank you!\n\n---\n\nMessage sent from Support contact form.'
72+
const expectedResponse: Contact[] = [
73+
{
74+
fromEmail: contactDTO.fromEmail,
75+
subject: 'Root Support Request: ' + contactDTO.subject,
76+
body: bodyMessage
77+
}
78+
]
79+
80+
const contactRepositoryStub = <IContactRepository>{}
81+
82+
contactRepositoryStub.submitContactInfo = jest.fn().mockResolvedValue(expectedResponse)
83+
const sut = new SubmitContactInfo(contactRepositoryStub)
84+
const actual = await sut.execute(contactDTO)
85+
expect(actual).toEqual(expectedResponse)
86+
expect(contactRepositoryStub.submitContactInfo).toHaveBeenCalledWith(contactDTO)
87+
})
88+
89+
test('should return error result once there is a invalid targetId', async () => {
6190
const contactDTO: ContactDTO = {
6291
targetId: 0,
6392
subject: '',

0 commit comments

Comments
 (0)