Merge pull request #1946 from gradido/1883-remove-the-animated-coins-in-the-profile-settings

1883 remove the animated coins in the profile settings
This commit is contained in:
Alexander Friedland 2022-05-30 11:32:01 +02:00 committed by GitHub
commit afde83e2cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 17 additions and 320 deletions

View File

@ -19,7 +19,4 @@ export default class UpdateUserInfosArgs {
@Field({ nullable: true })
passwordNew?: string
@Field({ nullable: true })
coinanimation?: boolean
}

View File

@ -1,5 +0,0 @@
enum Setting {
COIN_ANIMATION = 'coinanimation',
}
export { Setting }

View File

@ -15,8 +15,6 @@ export class User {
this.language = user.language
this.publisherId = user.publisherId
this.isAdmin = user.isAdmin
// TODO
this.coinanimation = null
this.klickTipp = null
this.hasElopage = null
}
@ -61,11 +59,6 @@ export class User {
@Field(() => Date, { nullable: true })
isAdmin: Date | null
// TODO this is a bit inconsistent with what we query from the database
// therefore all those fields are now nullable with default value null
@Field(() => Boolean, { nullable: true })
coinanimation: boolean | null
@Field(() => KlickTipp, { nullable: true })
klickTipp: KlickTipp | null

View File

@ -344,7 +344,6 @@ describe('UserResolver', () => {
expect.objectContaining({
data: {
login: {
coinanimation: true,
email: 'bibi@bloxberg.de',
firstName: 'Bibi',
hasElopage: false,
@ -479,7 +478,6 @@ describe('UserResolver', () => {
firstName: 'Bibi',
lastName: 'Bloxberg',
language: 'de',
coinanimation: true,
klickTipp: {
newsletterState: false,
},

View File

@ -3,7 +3,7 @@ import { backendLogger as logger } from '@/server/logger'
import { Context, getUser } from '@/server/context'
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
import { getConnection, getCustomRepository } from '@dbTools/typeorm'
import { getConnection } from '@dbTools/typeorm'
import CONFIG from '@/config'
import { User } from '@model/User'
import { User as DbUser } from '@entity/User'
@ -13,8 +13,6 @@ import CreateUserArgs from '@arg/CreateUserArgs'
import UnsecureLoginArgs from '@arg/UnsecureLoginArgs'
import UpdateUserInfosArgs from '@arg/UpdateUserInfosArgs'
import { klicktippNewsletterStateMiddleware } from '@/middleware/klicktippMiddleware'
import { UserSettingRepository } from '@repository/UserSettingRepository'
import { Setting } from '@enum/Setting'
import { OptInType } from '@enum/OptInType'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { sendResetPasswordEmail as sendResetPasswordEmailMailer } from '@/mailer/sendResetPasswordEmail'
@ -228,15 +226,6 @@ export class UserResolver {
// Elopage Status & Stored PublisherId
user.hasElopage = await this.hasElopage(context)
// coinAnimation
const userSettingRepository = getCustomRepository(UserSettingRepository)
const coinanimation = await userSettingRepository
.readBoolean(userEntity.id, Setting.COIN_ANIMATION)
.catch((error) => {
logger.error('error:', error)
throw new Error(error)
})
user.coinanimation = coinanimation
logger.debug(`verifyLogin... successful: ${user.firstName}.${user.lastName}, ${user.email}`)
return user
}
@ -294,15 +283,6 @@ export class UserResolver {
DbUser.save(dbUser)
}
// coinAnimation
const userSettingRepository = getCustomRepository(UserSettingRepository)
const coinanimation = await userSettingRepository
.readBoolean(dbUser.id, Setting.COIN_ANIMATION)
.catch((error) => {
throw new Error(error)
})
user.coinanimation = coinanimation
context.setHeaders.push({
key: 'token',
value: encode(dbUser.pubKey),
@ -598,12 +578,10 @@ export class UserResolver {
@Mutation(() => Boolean)
async updateUserInfos(
@Args()
{ firstName, lastName, language, password, passwordNew, coinanimation }: UpdateUserInfosArgs,
{ firstName, lastName, language, password, passwordNew }: UpdateUserInfosArgs,
@Ctx() context: Context,
): Promise<boolean> {
logger.info(
`updateUserInfos(${firstName}, ${lastName}, ${language}, ***, ***, ${coinanimation})...`,
)
logger.info(`updateUserInfos(${firstName}, ${lastName}, ${language}, ***, ***)...`)
const userEntity = getUser(context)
if (firstName) {
@ -655,15 +633,6 @@ export class UserResolver {
await queryRunner.startTransaction('READ UNCOMMITTED')
try {
if (coinanimation !== null && coinanimation !== undefined) {
queryRunner.manager
.getCustomRepository(UserSettingRepository)
.setOrUpdate(userEntity.id, Setting.COIN_ANIMATION, coinanimation.toString())
.catch((error) => {
throw new Error('error saving coinanimation: ' + error)
})
}
await queryRunner.manager.save(userEntity).catch((error) => {
throw new Error('error saving user: ' + error)
})

View File

@ -31,7 +31,6 @@ export const updateUserInfos = gql`
$password: String
$passwordNew: String
$locale: String
$coinanimation: Boolean
) {
updateUserInfos(
firstName: $firstName
@ -39,7 +38,6 @@ export const updateUserInfos = gql`
password: $password
passwordNew: $passwordNew
language: $locale
coinanimation: $coinanimation
)
}
`

View File

@ -8,7 +8,6 @@ export const login = gql`
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}
@ -26,7 +25,6 @@ export const verifyLogin = gql`
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}

View File

@ -1,33 +1,22 @@
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { UserSetting } from '@entity/UserSetting'
import { Setting } from '@enum/Setting'
import { isStringBoolean } from '@/util/validate'
@EntityRepository(UserSetting)
export class UserSettingRepository extends Repository<UserSetting> {
async setOrUpdate(userId: number, key: Setting, value: string): Promise<UserSetting> {
switch (key) {
case Setting.COIN_ANIMATION:
if (!isStringBoolean(value)) {
throw new Error("coinanimation value isn't boolean")
}
break
default:
throw new Error("key isn't defined: " + key)
}
let entity = await this.findOne({ userId: userId, key: key })
async setOrUpdate(userId: number, value: string): Promise<UserSetting> {
let entity = await this.findOne({ userId: userId })
if (!entity) {
entity = new UserSetting()
entity.userId = userId
entity.key = key
}
entity.value = value
return this.save(entity)
}
async readBoolean(userId: number, key: Setting): Promise<boolean> {
const entity = await this.findOne({ userId: userId, key: key })
async readBoolean(userId: number): Promise<boolean> {
const entity = await this.findOne({ userId: userId })
if (!entity || !isStringBoolean(entity.value)) {
return true
}

View File

@ -1,127 +0,0 @@
import { mount } from '@vue/test-utils'
import UserCoinAnimation from './UserCoinAnimation'
import { updateUserInfos } from '@/graphql/mutations'
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
const localVue = global.localVue
const mockAPIcall = jest.fn()
const storeCommitMock = jest.fn()
describe('UserCard_CoinAnimation', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
$store: {
state: {
language: 'de',
coinanimation: true,
},
commit: storeCommitMock,
},
$apollo: {
mutate: mockAPIcall,
},
}
const Wrapper = () => {
return mount(UserCoinAnimation, { localVue, mocks })
}
describe('mount', () => {
beforeEach(() => {
jest.clearAllMocks()
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.find('div#formusercoinanimation').exists()).toBeTruthy()
})
it('has an edit BFormCheckbox switch', () => {
expect(wrapper.find('.Test-BFormCheckbox').exists()).toBeTruthy()
})
describe('enable with success', () => {
beforeEach(async () => {
await wrapper.setData({ CoinAnimationStatus: false })
mockAPIcall.mockResolvedValue({
data: {
updateUserInfos: {
validValues: 1,
},
},
})
await wrapper.find('input').setChecked()
})
it('calls the updateUserInfos mutation', () => {
expect(mockAPIcall).toBeCalledWith({
mutation: updateUserInfos,
variables: {
coinanimation: true,
},
})
})
it('updates the store', () => {
expect(storeCommitMock).toBeCalledWith('coinanimation', true)
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('settings.coinanimation.True')
})
})
describe('disable with success', () => {
beforeEach(async () => {
await wrapper.setData({ CoinAnimationStatus: true })
mockAPIcall.mockResolvedValue({
data: {
updateUserInfos: {
validValues: 1,
},
},
})
await wrapper.find('input').setChecked(false)
})
it('calls the subscribe mutation', () => {
expect(mockAPIcall).toBeCalledWith({
mutation: updateUserInfos,
variables: {
coinanimation: false,
},
})
})
it('updates the store', () => {
expect(storeCommitMock).toBeCalledWith('coinanimation', false)
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('settings.coinanimation.False')
})
})
describe('disable with server error', () => {
beforeEach(() => {
mockAPIcall.mockRejectedValue({
message: 'Ouch',
})
wrapper.find('input').trigger('change')
})
it('resets the CoinAnimationStatus', () => {
expect(wrapper.vm.CoinAnimationStatus).toBeTruthy()
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Ouch')
})
})
})
})

View File

@ -1,65 +0,0 @@
<template>
<b-card
id="formusercoinanimation"
class="bg-transparent gradido-custom-background gradido-no-border-radius"
>
<div>
<b-row class="mb-3">
<b-col class="mb-2 col-12">
<small>
<b>{{ $t('settings.coinanimation.coinanimation') }}</b>
</small>
</b-col>
<b-col class="col-12">
<b-form-checkbox
class="Test-BFormCheckbox"
v-model="CoinAnimationStatus"
name="check-button"
switch
@change="onSubmit"
>
{{
CoinAnimationStatus
? $t('settings.coinanimation.True')
: $t('settings.coinanimation.False')
}}
</b-form-checkbox>
</b-col>
</b-row>
</div>
</b-card>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserCoinAnimation',
data() {
return {
CoinAnimationStatus: this.$store.state.coinanimation,
}
},
methods: {
async onSubmit() {
this.$apollo
.mutate({
mutation: updateUserInfos,
variables: {
coinanimation: this.CoinAnimationStatus,
},
})
.then(() => {
this.$store.commit('coinanimation', this.CoinAnimationStatus)
this.toastSuccess(
this.CoinAnimationStatus
? this.$t('settings.coinanimation.True')
: this.$t('settings.coinanimation.False'),
)
})
.catch((error) => {
this.CoinAnimationStatus = this.$store.state.coinanimation
this.toastError(error.message)
})
},
},
}
</script>

View File

@ -31,7 +31,6 @@ export const updateUserInfos = gql`
$password: String
$passwordNew: String
$locale: String
$coinanimation: Boolean
) {
updateUserInfos(
firstName: $firstName
@ -39,7 +38,6 @@ export const updateUserInfos = gql`
password: $password
passwordNew: $passwordNew
language: $locale
coinanimation: $coinanimation
)
}
`

View File

@ -7,7 +7,6 @@ export const login = gql`
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}
@ -25,7 +24,6 @@ export const verifyLogin = gql`
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}

View File

@ -186,11 +186,6 @@
"send_gdd": "GDD versenden",
"send_per_link": "GDD versenden per Link",
"settings": {
"coinanimation": {
"coinanimation": "Münzanimation",
"False": "Münzanimation ausgeschaltet",
"True": "Münzanimation eingeschaltet"
},
"language": {
"changeLanguage": "Sprache ändern",
"de": "Deutsch",

View File

@ -186,11 +186,6 @@
"send_gdd": "GDD send",
"send_per_link": "GDD send via link",
"settings": {
"coinanimation": {
"coinanimation": "Coin animation",
"False": "Coin animation disabled",
"True": "Coin animation enabled"
},
"language": {
"changeLanguage": "Change language",
"de": "Deutsch",

View File

@ -38,9 +38,5 @@ describe('Profile', () => {
it('has a user change newsletter form', () => {
expect(wrapper.findComponent({ name: 'UserNewsletter' }).exists()).toBeTruthy()
})
it('has a user change coin animation form', () => {
expect(wrapper.findComponent({ name: 'UserCoinAnimation' }).exists()).toBeTruthy()
})
})
})

View File

@ -8,8 +8,6 @@
<user-language />
<hr />
<user-newsletter />
<hr />
<user-coin-animation />
</div>
</template>
<script>
@ -18,7 +16,6 @@ import UserData from '@/components/UserSettings/UserData.vue'
import UserPassword from '@/components/UserSettings/UserPassword.vue'
import UserLanguage from '@/components/UserSettings/UserLanguage.vue'
import UserNewsletter from '@/components/UserSettings/UserNewsletter.vue'
import UserCoinAnimation from '@/components/UserSettings/UserCoinAnimation.vue'
export default {
name: 'Profile',
@ -28,7 +25,6 @@ export default {
UserPassword,
UserLanguage,
UserNewsletter,
UserCoinAnimation,
},
props: {
balance: { type: Number, default: 0 },

View File

@ -38,9 +38,6 @@ export const mutations = {
isAdmin: (state, isAdmin) => {
state.isAdmin = !!isAdmin
},
coinanimation: (state, coinanimation) => {
state.coinanimation = coinanimation
},
hasElopage: (state, hasElopage) => {
state.hasElopage = hasElopage
},
@ -53,7 +50,6 @@ export const actions = {
// commit('username', data.username)
commit('firstName', data.firstName)
commit('lastName', data.lastName)
commit('coinanimation', data.coinanimation)
commit('newsletterState', data.klickTipp.newsletterState)
commit('hasElopage', data.hasElopage)
commit('publisherId', data.publisherId)
@ -65,7 +61,6 @@ export const actions = {
// commit('username', '')
commit('firstName', '')
commit('lastName', '')
commit('coinanimation', true)
commit('newsletterState', null)
commit('hasElopage', false)
commit('publisherId', null)
@ -91,7 +86,6 @@ try {
// username: '',
token: null,
isAdmin: false,
coinanimation: true,
newsletterState: null,
hasElopage: false,
publisherId: null,

View File

@ -20,7 +20,6 @@ const {
token,
firstName,
lastName,
coinanimation,
newsletterState,
publisherId,
isAdmin,
@ -78,14 +77,6 @@ describe('Vuex store', () => {
})
})
describe('coinanimation', () => {
it('sets the state of coinanimation', () => {
const state = { coinanimation: true }
coinanimation(state, false)
expect(state.coinanimation).toEqual(false)
})
})
describe('newsletterState', () => {
it('sets the state of newsletterState', () => {
const state = { newsletterState: null }
@ -134,7 +125,6 @@ describe('Vuex store', () => {
language: 'de',
firstName: 'Peter',
lastName: 'Lustig',
coinanimation: false,
klickTipp: {
newsletterState: true,
},
@ -145,7 +135,7 @@ describe('Vuex store', () => {
it('calls nine commits', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenCalledTimes(9)
expect(commit).toHaveBeenCalledTimes(8)
})
it('commits email', () => {
@ -168,29 +158,24 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(4, 'lastName', 'Lustig')
})
it('commits coinanimation', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(5, 'coinanimation', false)
})
it('commits newsletterState', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(6, 'newsletterState', true)
expect(commit).toHaveBeenNthCalledWith(5, 'newsletterState', true)
})
it('commits hasElopage', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(7, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(6, 'hasElopage', false)
})
it('commits publisherId', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(8, 'publisherId', 1234)
expect(commit).toHaveBeenNthCalledWith(7, 'publisherId', 1234)
})
it('commits isAdmin', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(9, 'isAdmin', true)
expect(commit).toHaveBeenNthCalledWith(8, 'isAdmin', true)
})
})
@ -200,7 +185,7 @@ describe('Vuex store', () => {
it('calls nine commits', () => {
logout({ commit, state })
expect(commit).toHaveBeenCalledTimes(9)
expect(commit).toHaveBeenCalledTimes(8)
})
it('commits token', () => {
@ -223,29 +208,24 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(4, 'lastName', '')
})
it('commits coinanimation', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(5, 'coinanimation', true)
})
it('commits newsletterState', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(6, 'newsletterState', null)
expect(commit).toHaveBeenNthCalledWith(5, 'newsletterState', null)
})
it('commits hasElopage', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(7, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(6, 'hasElopage', false)
})
it('commits publisherId', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(8, 'publisherId', null)
expect(commit).toHaveBeenNthCalledWith(7, 'publisherId', null)
})
it('commits isAdmin', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(9, 'isAdmin', false)
expect(commit).toHaveBeenNthCalledWith(8, 'isAdmin', false)
})
// how to get this working?