mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into contribution-resolver-logs-and-events
This commit is contained in:
commit
87789aca5f
@ -62,13 +62,13 @@ The business events will be stored in database in the new table `EventProtocol`.
|
||||
|
||||
The following table lists for each event type the mapping between old and new key, the mandatory attributes, which have to be initialized at event occurence and to be written in the database event protocol table:
|
||||
|
||||
| EventType - old key | EventType - new key | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount |
|
||||
| EventKey | EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount |
|
||||
| :-------------------------------- | :------------------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: |
|
||||
| BASIC | BasicEvent | x | x | x | | | | | | |
|
||||
| VISIT_GRADIDO | VisitGradidoEvent | x | x | x | | | | | | |
|
||||
| REGISTER | RegisterEvent | x | x | x | x | | | | | |
|
||||
| LOGIN | LoginEvent | x | x | x | x | | | | | |
|
||||
| | VerifyRedeemEvent | | | | | | | | | |
|
||||
| VERIFY_REDEEM | VerifyRedeemEvent | x | x | x | x | | | (x) | (x) | |
|
||||
| REDEEM_REGISTER | RedeemRegisterEvent | x | x | x | x | | | (x) | (x) | |
|
||||
| REDEEM_LOGIN | RedeemLoginEvent | x | x | x | x | | | (x) | (x) | |
|
||||
| ACTIVATE_ACCOUNT | ActivateAccountEvent | x | x | x | x | | | | | |
|
||||
@ -82,20 +82,20 @@ The following table lists for each event type the mapping between old and new ke
|
||||
| TRANSACTION_SEND_REDEEM | TransactionLinkRedeemEvent | x | x | x | x | x | x | x | | x |
|
||||
| CONTRIBUTION_CREATE | ContributionCreateEvent | x | x | x | x | | | | x | x |
|
||||
| CONTRIBUTION_CONFIRM | ContributionConfirmEvent | x | x | x | x | x | x | | x | x |
|
||||
| | ContributionDenyEvent | x | x | x | x | x | x | | x | x |
|
||||
| CONTRIBUTION_DENY | ContributionDenyEvent | x | x | x | x | x | x | | x | x |
|
||||
| CONTRIBUTION_LINK_DEFINE | ContributionLinkDefineEvent | x | x | x | x | | | | | x |
|
||||
| CONTRIBUTION_LINK_ACTIVATE_REDEEM | ContributionLinkRedeemEvent | x | x | x | x | | | | x | x |
|
||||
| | UserCreateContributionMessageEvent | x | x | x | x | | | | x | x |
|
||||
| | AdminCreateContributionMessageEvent | x | x | x | x | | | | x | x |
|
||||
| | LogoutEvent | x | x | x | x | | | | x | x |
|
||||
| USER_CREATES_CONTRIBUTION_MESSAGE | UserCreateContributionMessageEvent | x | x | x | x | | | | x | x |
|
||||
| ADMIN_CREATES_CONTRIBUTION_MESSAGE | AdminCreateContributionMessageEvent | x | x | x | x | | | | x | x |
|
||||
| LOGOUT | LogoutEvent | x | x | x | x | | | | | |
|
||||
| SEND_CONFIRMATION_EMAIL | SendConfirmEmailEvent | x | x | x | x | | | | | |
|
||||
| | SendAccountMultiRegistrationEmailEvent | x | x | x | x | | | | | |
|
||||
| | SendForgotPasswordEmailEvent | x | x | x | x | | | | | |
|
||||
| | SendTransactionSendEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| | SendTransactionReceiveEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| | SendAddedContributionEmailEvent | x | x | x | x | | | | x | x |
|
||||
| | SendContributionConfirmEmailEvent | x | x | x | x | | | | x | x |
|
||||
| | SendTransactionLinkRedeemEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| SEND_ACCOUNT_MULTIREGISTRATION_EMAIL | SendAccountMultiRegistrationEmailEvent | x | x | x | x | | | | | |
|
||||
| SEND_FORGOT_PASSWORD_EMAIL | SendForgotPasswordEmailEvent | x | x | x | x | | | | | |
|
||||
| SEND_TRANSACTION_SEND_EMAIL | SendTransactionSendEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| SEND_TRANSACTION_RECEIVE_EMAIL | SendTransactionReceiveEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| SEND_ADDED_CONTRIBUTION_EMAIL | SendAddedContributionEmailEvent | x | x | x | x | | | | x | x |
|
||||
| SEND_CONTRIBUTION_CONFIRM_EMAIL | SendContributionConfirmEmailEvent | x | x | x | x | | | | x | x |
|
||||
| SEND_TRANSACTION_LINK_REDEEM_EMAIL | SendTransactionLinkRedeemEmailEvent | x | x | x | x | x | x | x | | x |
|
||||
| TRANSACTION_REPEATE_REDEEM | - | | | | | | | | | |
|
||||
| TRANSACTION_RECEIVE_REDEEM | - | | | | | | | | | |
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ const mocks = {
|
||||
$store: {
|
||||
state: {
|
||||
token: null,
|
||||
tokenTime: null,
|
||||
email: 'bibi@bloxberg.de',
|
||||
},
|
||||
},
|
||||
@ -68,7 +69,7 @@ describe('TransactionLink', () => {
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
beforeAll(() => {
|
||||
jest.clearAllMocks()
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
@ -214,112 +215,159 @@ describe('TransactionLink', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('token in store and own link', () => {
|
||||
beforeEach(() => {
|
||||
describe('token in store', () => {
|
||||
beforeAll(() => {
|
||||
mocks.$store.state.token = 'token'
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
queryTransactionLink: {
|
||||
__typename: 'TransactionLink',
|
||||
id: 92,
|
||||
amount: '22',
|
||||
memo: 'Abrakadabra drei, vier, fünf, sechs, hier steht jetzt ein Memotext! Hex hex ',
|
||||
createdAt: '2022-03-17T16:10:28.000Z',
|
||||
validUntil: transactionLinkValidExpireDate(),
|
||||
redeemedAt: null,
|
||||
deletedAt: null,
|
||||
user: { firstName: 'Bibi', publisherId: 0, email: 'bibi@bloxberg.de' },
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a RedeemSelfCreator component', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemSelfCreator' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a no redeem text', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemSelfCreator' }).text()).toContain(
|
||||
'gdd_per_link.no-redeem',
|
||||
)
|
||||
})
|
||||
|
||||
it.skip('has a link to transaction page', () => {
|
||||
expect(wrapper.find('a[target="/transactions"]').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid link', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store.state.token = 'token'
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
queryTransactionLink: {
|
||||
__typename: 'TransactionLink',
|
||||
id: 92,
|
||||
amount: '22',
|
||||
memo: 'Abrakadabra drei, vier, fünf, sechs, hier steht jetzt ein Memotext! Hex hex ',
|
||||
createdAt: '2022-03-17T16:10:28.000Z',
|
||||
validUntil: transactionLinkValidExpireDate(),
|
||||
redeemedAt: null,
|
||||
deletedAt: null,
|
||||
user: { firstName: 'Peter', publisherId: 0, email: 'peter@listig.de' },
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a RedeemValid component', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemValid' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a button with redeem text', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemValid' }).find('button').text()).toBe(
|
||||
'gdd_per_link.redeem',
|
||||
)
|
||||
})
|
||||
|
||||
describe('redeem link with success', () => {
|
||||
beforeEach(async () => {
|
||||
apolloMutateMock.mockResolvedValue()
|
||||
await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click')
|
||||
describe('sufficient token time in store', () => {
|
||||
beforeAll(() => {
|
||||
mocks.$store.state.tokenTime = Math.floor(Date.now() / 1000) + 20
|
||||
})
|
||||
|
||||
it('calls the API', () => {
|
||||
expect(apolloMutateMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
mutation: redeemTransactionLink,
|
||||
variables: {
|
||||
code: 'some-code',
|
||||
describe('own link', () => {
|
||||
beforeAll(() => {
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
queryTransactionLink: {
|
||||
__typename: 'TransactionLink',
|
||||
id: 92,
|
||||
amount: '22',
|
||||
memo:
|
||||
'Abrakadabra drei, vier, fünf, sechs, hier steht jetzt ein Memotext! Hex hex ',
|
||||
createdAt: '2022-03-17T16:10:28.000Z',
|
||||
validUntil: transactionLinkValidExpireDate(),
|
||||
redeemedAt: null,
|
||||
deletedAt: null,
|
||||
user: { firstName: 'Bibi', publisherId: 0, email: 'bibi@bloxberg.de' },
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a RedeemSelfCreator component', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemSelfCreator' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a no redeem text', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemSelfCreator' }).text()).toContain(
|
||||
'gdd_per_link.no-redeem',
|
||||
)
|
||||
})
|
||||
|
||||
it.skip('has a link to transaction page', () => {
|
||||
expect(wrapper.find('a[target="/transactions"]').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
it('toasts a success message', () => {
|
||||
expect(mocks.$t).toBeCalledWith('gdd_per_link.redeem')
|
||||
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.redeemed; ')
|
||||
})
|
||||
describe('valid link', () => {
|
||||
beforeAll(() => {
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
queryTransactionLink: {
|
||||
__typename: 'TransactionLink',
|
||||
id: 92,
|
||||
amount: '22',
|
||||
memo:
|
||||
'Abrakadabra drei, vier, fünf, sechs, hier steht jetzt ein Memotext! Hex hex ',
|
||||
createdAt: '2022-03-17T16:10:28.000Z',
|
||||
validUntil: transactionLinkValidExpireDate(),
|
||||
redeemedAt: null,
|
||||
deletedAt: null,
|
||||
user: { firstName: 'Peter', publisherId: 0, email: 'peter@listig.de' },
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('pushes the route to overview', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/overview')
|
||||
it('has a RedeemValid component', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemValid' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a button with redeem text', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemValid' }).find('button').text()).toBe(
|
||||
'gdd_per_link.redeem',
|
||||
)
|
||||
})
|
||||
|
||||
describe('redeem link with success', () => {
|
||||
beforeAll(async () => {
|
||||
apolloMutateMock.mockResolvedValue()
|
||||
await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click')
|
||||
})
|
||||
|
||||
it('calls the API', () => {
|
||||
expect(apolloMutateMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
mutation: redeemTransactionLink,
|
||||
variables: {
|
||||
code: 'some-code',
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('toasts a success message', () => {
|
||||
expect(mocks.$t).toBeCalledWith('gdd_per_link.redeem')
|
||||
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.redeemed; ')
|
||||
})
|
||||
|
||||
it('pushes the route to overview', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/overview')
|
||||
})
|
||||
})
|
||||
|
||||
describe('redeem link with error', () => {
|
||||
beforeAll(async () => {
|
||||
apolloMutateMock.mockRejectedValue({ message: 'Oh Noo!' })
|
||||
await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click')
|
||||
})
|
||||
|
||||
it('toasts an error message', () => {
|
||||
expect(toastErrorSpy).toBeCalledWith('Oh Noo!')
|
||||
})
|
||||
|
||||
it('pushes the route to overview', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/overview')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('redeem link with error', () => {
|
||||
beforeEach(async () => {
|
||||
apolloMutateMock.mockRejectedValue({ message: 'Oh Noo!' })
|
||||
await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click')
|
||||
describe('no sufficient token time in store', () => {
|
||||
beforeAll(() => {
|
||||
mocks.$store.state.tokenTime = 1665125185
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
queryTransactionLink: {
|
||||
__typename: 'TransactionLink',
|
||||
id: 92,
|
||||
amount: '22',
|
||||
memo:
|
||||
'Abrakadabra drei, vier, fünf, sechs, hier steht jetzt ein Memotext! Hex hex ',
|
||||
createdAt: '2022-03-17T16:10:28.000Z',
|
||||
validUntil: transactionLinkValidExpireDate(),
|
||||
redeemedAt: null,
|
||||
deletedAt: null,
|
||||
user: { firstName: 'Bibi', publisherId: 0, email: 'bibi@bloxberg.de' },
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('toasts an error message', () => {
|
||||
expect(toastErrorSpy).toBeCalledWith('Oh Noo!')
|
||||
it('has a RedeemLoggedOut component', () => {
|
||||
expect(wrapper.findComponent({ name: 'RedeemLoggedOut' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('pushes the route to overview', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/overview')
|
||||
it('has a link to register with code', () => {
|
||||
expect(wrapper.find('a[href="/register/some-code"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a link to login with code', () => {
|
||||
expect(wrapper.find('a[href="/login/some-code"]').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -103,6 +103,12 @@ export default {
|
||||
isContributionLink() {
|
||||
return this.$route.params.code.search(/^CL-/) === 0
|
||||
},
|
||||
tokenExpiresInSeconds() {
|
||||
const remainingSecs = Math.floor(
|
||||
(new Date(this.$store.state.tokenTime * 1000).getTime() - new Date().getTime()) / 1000,
|
||||
)
|
||||
return remainingSecs <= 0 ? 0 : remainingSecs
|
||||
},
|
||||
itemType() {
|
||||
// link is deleted: at, from
|
||||
if (this.linkData.deletedAt) {
|
||||
@ -130,7 +136,9 @@ export default {
|
||||
return `TEXT`
|
||||
}
|
||||
|
||||
if (this.$store.state.token) {
|
||||
if (this.$store.state.token && this.$store.state.tokenTime) {
|
||||
if (this.tokenExpiresInSeconds < 5) return `LOGGED_OUT`
|
||||
|
||||
// logged in, nicht berechtigt einzulösen, eigener link
|
||||
if (this.linkData.user && this.$store.state.email === this.linkData.user.email) {
|
||||
return `SELF_CREATOR`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user