Skip to content

Commit 38c36d2

Browse files
committed
Changed: RecreateApiToken use case to return ApiTokenInfo object
1 parent 32dbe99 commit 38c36d2

File tree

8 files changed

+53
-29
lines changed

8 files changed

+53
-29
lines changed

src/users/domain/repositories/IUsersRepository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ import { AuthenticatedUser } from '../models/AuthenticatedUser'
33

44
export interface IUsersRepository {
55
getCurrentAuthenticatedUser(): Promise<AuthenticatedUser>
6-
recreateApiToken(): Promise<string>
6+
recreateApiToken(): Promise<ApiTokenInfo>
77
getCurrentApiToken(): Promise<ApiTokenInfo>
88
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ApiTokenInfo } from '../models/ApiTokenInfo'
23
import { IUsersRepository } from '../repositories/IUsersRepository'
34

4-
export class RecreateApiToken implements UseCase<string> {
5+
export class RecreateApiToken implements UseCase<ApiTokenInfo> {
56
private usersRepository: IUsersRepository
67

78
constructor(usersRepository: IUsersRepository) {
89
this.usersRepository = usersRepository
910
}
1011

1112
/**
12-
* Reacreates the API token of the current authenticated user and returns the new one.
13+
* Reacreates the API token of the current authenticated user in ApiConfig and returns the new API token info.
1314
*
14-
* @returns {Promise<AuthenticatedUser>}
15+
* @returns {Promise<ApiTokenInfo>}
1516
*/
16-
async execute(): Promise<string> {
17+
async execute(): Promise<ApiTokenInfo> {
1718
return await this.usersRepository.recreateApiToken()
1819
}
1920
}

src/users/infra/repositories/UsersRepository.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { IUsersRepository } from '../../domain/repositories/IUsersRepository'
33
import { AuthenticatedUser } from '../../domain/models/AuthenticatedUser'
44
import { AxiosResponse } from 'axios'
55
import { ApiTokenInfo } from '../../domain/models/ApiTokenInfo'
6-
import { transformApiTokenInfoResponseToApiTokenInfo } from './transformers/apiTokenInfoTransformers'
6+
import {
7+
transformGetApiTokenResponseToApiTokenInfo,
8+
transformRecreateApiTokenResponseToApiTokenInfo
9+
} from './transformers/apiTokenInfoTransformers'
710

811
export class UsersRepository extends ApiRepository implements IUsersRepository {
912
private readonly usersResourceName: string = 'users'
@@ -16,17 +19,17 @@ export class UsersRepository extends ApiRepository implements IUsersRepository {
1619
})
1720
}
1821

19-
public async recreateApiToken(): Promise<string> {
20-
return this.doPost(`/${this.usersResourceName}/token/recreate`, {})
21-
.then((response) => response.data.data.message.split(' ').pop())
22+
public async recreateApiToken(): Promise<ApiTokenInfo> {
23+
return this.doPost(`/${this.usersResourceName}/token/recreate?returnExpiration=true`, {})
24+
.then((response) => transformRecreateApiTokenResponseToApiTokenInfo(response))
2225
.catch((error) => {
2326
throw error
2427
})
2528
}
2629

2730
public async getCurrentApiToken(): Promise<ApiTokenInfo> {
2831
return this.doGet(`/${this.usersResourceName}/token`, true)
29-
.then((response) => transformApiTokenInfoResponseToApiTokenInfo(response))
32+
.then((response) => transformGetApiTokenResponseToApiTokenInfo(response))
3033
.catch((error) => {
3134
throw error
3235
})

src/users/infra/repositories/transformers/apiTokenInfoTransformers.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { AxiosResponse } from 'axios'
22
import { ApiTokenInfo } from '../../../domain/models/ApiTokenInfo'
33

4-
export const transformApiTokenInfoResponseToApiTokenInfo = (
4+
export const transformGetApiTokenResponseToApiTokenInfo = (
55
response: AxiosResponse
66
): ApiTokenInfo => {
77
const apiTokenInfoPayload = response.data.data
@@ -12,3 +12,15 @@ export const transformApiTokenInfoResponseToApiTokenInfo = (
1212
expirationDate: new Date(expirationDateFormattedTimestamp)
1313
}
1414
}
15+
16+
export const transformRecreateApiTokenResponseToApiTokenInfo = (
17+
response: AxiosResponse
18+
): ApiTokenInfo => {
19+
const apiTokenInfoPayload = response.data.data
20+
const messageParts = apiTokenInfoPayload.message.split(' ')
21+
const expirationDateFormattedTimestamp = `${messageParts[9]}T${messageParts[10]}`
22+
return {
23+
apiToken: messageParts[5],
24+
expirationDate: new Date(expirationDateFormattedTimestamp)
25+
}
26+
}

test/functional/users/RecreateApiToken.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ describe('execute', () => {
2121
})
2222

2323
test('should successfully recreate the API token', async () => {
24-
const testApiToken = await createApiTokenViaApi()
24+
const testApiToken = await createApiTokenViaApi('recreateApiTokenFTUser')
2525
ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, testApiToken)
26-
const actualNewApiToken = await recreateApiToken.execute()
27-
expect(actualNewApiToken).not.toBe(testApiToken)
26+
const actualRecreatedApiTokenInfo = await recreateApiToken.execute()
27+
expect(actualRecreatedApiTokenInfo.apiToken).not.toBeUndefined()
28+
expect(actualRecreatedApiTokenInfo.apiToken).not.toBe(testApiToken)
29+
expect(typeof actualRecreatedApiTokenInfo.expirationDate).toBe('object')
2830
})
2931
})

test/integration/users/UsersRepository.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ describe('UsersRepository', () => {
3838
})
3939

4040
describe('recreateApiToken', () => {
41-
test('should recreate API token when valid authentication is provided', async () => {
42-
const testApiToken = await createApiTokenViaApi()
41+
test('should recreate API token and return the new API token info when valid authentication is provided', async () => {
42+
const testApiToken = await createApiTokenViaApi('recreateApiTokenITUser')
4343
ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, testApiToken)
44-
const actualRecreatedApiToken = await sut.recreateApiToken()
45-
expect(actualRecreatedApiToken).not.toBe(testApiToken)
44+
const actualRecreatedApiTokenInfo = await sut.recreateApiToken()
45+
expect(actualRecreatedApiTokenInfo.apiToken).not.toBeUndefined()
46+
expect(actualRecreatedApiTokenInfo.apiToken).not.toBe(testApiToken)
47+
expect(typeof actualRecreatedApiTokenInfo.expirationDate).toBe('object')
4648
})
4749

4850
test('should return error when authentication is not valid', async () => {
@@ -61,6 +63,7 @@ describe('UsersRepository', () => {
6163
process.env.TEST_API_KEY
6264
)
6365
const actualApiTokenInfo = await sut.getCurrentApiToken()
66+
expect(actualApiTokenInfo.apiToken).not.toBeUndefined()
6467
expect(actualApiTokenInfo.apiToken).toBe(process.env.TEST_API_KEY)
6568
expect(typeof actualApiTokenInfo.expirationDate).toBe('object')
6669
})
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import axios from 'axios'
22
import { TestConstants } from '../TestConstants'
33

4-
const CREATE_USER_ENDPOINT = '/builtin-users?key=burrito&password=testuser'
5-
const API_TOKEN_USER_ENDPOINT = '/builtin-users/testuser/api-token'
6-
7-
export const createApiTokenViaApi = async (): Promise<string> => {
4+
export const createApiTokenViaApi = async (userName: string): Promise<string> => {
85
try {
96
await axios.post(
10-
`${TestConstants.TEST_API_URL}${CREATE_USER_ENDPOINT}`,
7+
`${TestConstants.TEST_API_URL}/builtin-users?key=burrito&password=${userName}`,
118
JSON.stringify({
12-
userName: 'testuser',
9+
userName: userName,
1310
firstName: 'John',
1411
lastName: 'Doe',
15-
email: 'test@test.com'
12+
email: `${userName}@test.com`
1613
}),
1714
{
1815
headers: {
@@ -21,9 +18,10 @@ export const createApiTokenViaApi = async (): Promise<string> => {
2118
}
2219
)
2320
return axios
24-
.get(`${TestConstants.TEST_API_URL}${API_TOKEN_USER_ENDPOINT}?password=testuser`)
21+
.get(`${TestConstants.TEST_API_URL}/builtin-users/${userName}/api-token?password=${userName}`)
2522
.then((response) => response.data.data.message)
2623
} catch (error) {
24+
console.log(error)
2725
throw new Error(`Error while creating API token`)
2826
}
2927
}

test/unit/users/RecreateApiToken.test.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import { IUsersRepository } from '../../../src/users/domain/repositories/IUsersRepository'
22
import { RecreateApiToken } from '../../../src/users/domain/useCases/RecreateApiToken'
33
import { WriteError } from '../../../src'
4+
import { ApiTokenInfo } from '../../../src/users/domain/models/ApiTokenInfo'
5+
import { TestConstants } from '../../testHelpers/TestConstants'
46

57
describe('execute', () => {
68
test('should return API token on repository success', async () => {
7-
const testNewToken = 'newToken'
9+
const testNewTokenInfo: ApiTokenInfo = {
10+
apiToken: TestConstants.TEST_DUMMY_API_KEY,
11+
expirationDate: new Date()
12+
}
813
const usersRepositoryStub: IUsersRepository = {} as IUsersRepository
9-
usersRepositoryStub.recreateApiToken = jest.fn().mockResolvedValue(testNewToken)
14+
usersRepositoryStub.recreateApiToken = jest.fn().mockResolvedValue(testNewTokenInfo)
1015
const sut = new RecreateApiToken(usersRepositoryStub)
1116

1217
const actual = await sut.execute()
1318

14-
expect(actual).toEqual(testNewToken)
19+
expect(actual).toEqual(testNewTokenInfo)
1520
})
1621

1722
test('should return error result on repository error', async () => {

0 commit comments

Comments
 (0)