mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge pull request #701 from gradido/apollo-client
feat: Vue Apollo Client
This commit is contained in:
commit
b9b74f4073
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -261,7 +261,7 @@ jobs:
|
|||||||
report_name: Coverage Frontend
|
report_name: Coverage Frontend
|
||||||
type: lcov
|
type: lcov
|
||||||
result_path: ./coverage/lcov.info
|
result_path: ./coverage/lcov.info
|
||||||
min_coverage: 47
|
min_coverage: 59
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|||||||
@ -1,16 +1,31 @@
|
|||||||
import { ArgsType, Field } from 'type-graphql'
|
import { ArgsType, Field, Int } from 'type-graphql'
|
||||||
|
|
||||||
@ArgsType()
|
@ArgsType()
|
||||||
export class GdtTransactionInput {
|
export class GdtTransactionInput {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
email: string
|
email: string
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Int, { nullable: true })
|
||||||
firstPage?: number
|
currentPage?: number
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Int, { nullable: true })
|
||||||
items?: number
|
pageSize?: number
|
||||||
|
|
||||||
@Field(() => String)
|
@Field(() => String, { nullable: true })
|
||||||
|
order?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
export class GdtTransactionSessionIdInput {
|
||||||
|
@Field(() => Number)
|
||||||
|
sessionId: number
|
||||||
|
|
||||||
|
@Field(() => Int, { nullable: true })
|
||||||
|
currentPage?: number
|
||||||
|
|
||||||
|
@Field(() => Int, { nullable: true })
|
||||||
|
pageSize?: number
|
||||||
|
|
||||||
|
@Field(() => String, { nullable: true })
|
||||||
order?: string
|
order?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ export class Decay {
|
|||||||
this.decayStart = json.decay_start
|
this.decayStart = json.decay_start
|
||||||
this.decayEnd = json.decay_end
|
this.decayEnd = json.decay_end
|
||||||
this.decayDuration = json.decay_duration
|
this.decayDuration = json.decay_duration
|
||||||
|
this.decayStartBlock = json.decay_start_block
|
||||||
}
|
}
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Number)
|
||||||
@ -22,4 +23,7 @@ export class Decay {
|
|||||||
|
|
||||||
@Field(() => String, { nullable: true })
|
@Field(() => String, { nullable: true })
|
||||||
decayDuration?: string
|
decayDuration?: string
|
||||||
|
|
||||||
|
@Field(() => Int, { nullable: true })
|
||||||
|
decayStartBlock?: number
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { ObjectType, Field } from 'type-graphql'
|
import { ObjectType, Field } from 'type-graphql'
|
||||||
|
|
||||||
export enum GdtEntryType {
|
export enum GdtEntryType {
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { GdtEntry } from './GdtEntry'
|
import { GdtEntry } from './GdtEntry'
|
||||||
import { ObjectType, Field } from 'type-graphql'
|
import { ObjectType, Field } from 'type-graphql'
|
||||||
|
|
||||||
@ -31,8 +33,8 @@ export class GdtEntryList {
|
|||||||
@Field(() => Number)
|
@Field(() => Number)
|
||||||
count: number
|
count: number
|
||||||
|
|
||||||
@Field(() => [GdtEntry])
|
@Field(() => [GdtEntry], { nullable: true })
|
||||||
gdtEntries: GdtEntry[]
|
gdtEntries?: GdtEntry[]
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Number)
|
||||||
gdtSum: number
|
gdtSum: number
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { Decay } from './Decay'
|
|||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class Transaction {
|
export class Transaction {
|
||||||
constructor(json: any) {
|
constructor(json: any) {
|
||||||
// console.log('Transaction constructor', json)
|
|
||||||
this.type = json.type
|
this.type = json.type
|
||||||
this.balance = Number(json.balance)
|
this.balance = Number(json.balance)
|
||||||
this.decayStart = json.decay_start
|
this.decayStart = json.decay_start
|
||||||
@ -43,8 +42,8 @@ export class Transaction {
|
|||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
memo: string
|
memo: string
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Number, { nullable: true })
|
||||||
transactionId: number
|
transactionId?: number
|
||||||
|
|
||||||
@Field({ nullable: true })
|
@Field({ nullable: true })
|
||||||
name?: string
|
name?: string
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import { Resolver, Query, /* Mutation, */ Args } from 'type-graphql'
|
import { Resolver, Query, /* Mutation, */ Args } from 'type-graphql'
|
||||||
import CONFIG from '../../config'
|
import CONFIG from '../../config'
|
||||||
import { GdtEntryList } from '../models/GdtEntryList'
|
import { GdtEntryList } from '../models/GdtEntryList'
|
||||||
import { GdtTransactionInput } from '../inputs/GdtInputs'
|
import { GdtTransactionSessionIdInput } from '../inputs/GdtInputs'
|
||||||
import { apiGet } from '../../apis/loginAPI'
|
import { apiGet } from '../../apis/loginAPI'
|
||||||
|
|
||||||
@Resolver()
|
@Resolver()
|
||||||
@ -10,13 +10,12 @@ export class GdtResolver {
|
|||||||
@Query(() => GdtEntryList)
|
@Query(() => GdtEntryList)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
async listGDTEntries(
|
async listGDTEntries(
|
||||||
@Args() { email, firstPage = 1, items = 5, order = 'DESC' }: GdtTransactionInput,
|
@Args()
|
||||||
|
{ currentPage = 1, pageSize = 5, order = 'DESC', sessionId }: GdtTransactionSessionIdInput,
|
||||||
): Promise<GdtEntryList> {
|
): Promise<GdtEntryList> {
|
||||||
email = email.trim().toLowerCase()
|
|
||||||
const result = await apiGet(
|
const result = await apiGet(
|
||||||
`${CONFIG.GDT_API_URL}/GdtEntries/listPerEmailApi/${email}/${firstPage}/${items}/${order}`,
|
`${CONFIG.COMMUNITY_API_URL}listGDTTransactions/${currentPage}/${pageSize}/${order}/${sessionId}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.data)
|
throw new Error(result.data)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Resolver, Query, /* Mutation, */ Args } from 'type-graphql'
|
import { Resolver, Query, Args } from 'type-graphql'
|
||||||
import CONFIG from '../../config'
|
import CONFIG from '../../config'
|
||||||
import { TransactionList } from '../models/Transaction'
|
import { TransactionList } from '../models/Transaction'
|
||||||
import { TransactionListInput, TransactionSendArgs } from '../inputs/TransactionInput'
|
import { TransactionListInput, TransactionSendArgs } from '../inputs/TransactionInput'
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
LOGIN_API_URL=http://localhost/login_api/
|
LOGIN_API_URL=http://localhost/login_api/
|
||||||
COMMUNITY_API_URL=http://localhost/api/
|
COMMUNITY_API_URL=http://localhost/api/
|
||||||
ALLOW_REGISTER=true
|
ALLOW_REGISTER=true
|
||||||
|
GRAPHQL_URI=http://localhost:4000/graphql
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
"@babel/preset-env": "^7.13.12",
|
"@babel/preset-env": "^7.13.12",
|
||||||
"@vue/cli-plugin-unit-jest": "^4.5.12",
|
"@vue/cli-plugin-unit-jest": "^4.5.12",
|
||||||
"@vue/test-utils": "^1.1.3",
|
"@vue/test-utils": "^1.1.3",
|
||||||
|
"apollo-boost": "^0.4.9",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-jest": "^26.6.3",
|
"babel-jest": "^26.6.3",
|
||||||
@ -45,6 +46,7 @@
|
|||||||
"flush-promises": "^1.0.2",
|
"flush-promises": "^1.0.2",
|
||||||
"fuse.js": "^3.2.0",
|
"fuse.js": "^3.2.0",
|
||||||
"google-maps": "^3.2.1",
|
"google-maps": "^3.2.1",
|
||||||
|
"graphql": "^15.5.1",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"jest-canvas-mock": "^2.3.1",
|
"jest-canvas-mock": "^2.3.1",
|
||||||
@ -59,6 +61,7 @@
|
|||||||
"sweetalert2": "^9.5.4",
|
"sweetalert2": "^9.5.4",
|
||||||
"vee-validate": "^3.4.5",
|
"vee-validate": "^3.4.5",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
|
"vue-apollo": "^3.0.7",
|
||||||
"vue-bootstrap-typeahead": "^0.2.6",
|
"vue-bootstrap-typeahead": "^0.2.6",
|
||||||
"vue-chartjs": "^3.5.0",
|
"vue-chartjs": "^3.5.0",
|
||||||
"vue-cli-plugin-i18n": "^1.0.1",
|
"vue-cli-plugin-i18n": "^1.0.1",
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import CONFIG from '../config'
|
|
||||||
|
|
||||||
const apiGet = async (url) => {
|
|
||||||
try {
|
|
||||||
const result = await axios.get(url)
|
|
||||||
if (result.status !== 200) {
|
|
||||||
throw new Error('HTTP Status Error ' + result.status)
|
|
||||||
}
|
|
||||||
if (result.data.state !== 'success') {
|
|
||||||
throw new Error(result.data.msg)
|
|
||||||
}
|
|
||||||
return { success: true, result }
|
|
||||||
} catch (error) {
|
|
||||||
return { success: false, result: error }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiPost = async (url, payload) => {
|
|
||||||
try {
|
|
||||||
const result = await axios.post(url, payload)
|
|
||||||
if (result.status !== 200) {
|
|
||||||
throw new Error('HTTP Status Error ' + result.status)
|
|
||||||
}
|
|
||||||
if (result.data.state !== 'success') {
|
|
||||||
throw new Error(result.data.msg)
|
|
||||||
}
|
|
||||||
return { success: true, result }
|
|
||||||
} catch (error) {
|
|
||||||
return { success: false, result: error }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const communityAPI = {
|
|
||||||
balance: async (sessionId) => {
|
|
||||||
return apiGet(CONFIG.COMMUNITY_API_URL + 'getBalance/' + sessionId)
|
|
||||||
},
|
|
||||||
transactions: async (sessionId, firstPage = 1, items = 5, order = 'DESC') => {
|
|
||||||
return apiGet(
|
|
||||||
`${CONFIG.COMMUNITY_API_URL}listTransactions/${firstPage}/${items}/${order}/${sessionId}`,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
transactionsgdt: async (sessionId, firstPage = 1, items = 5, order = 'DESC') => {
|
|
||||||
return apiGet(
|
|
||||||
`${CONFIG.COMMUNITY_API_URL}listGDTTransactions/${firstPage}/${items}/${order}/${sessionId}`,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
/* http://localhost/vue/public/json-example/admin_transactionGdt_list.json
|
|
||||||
http://localhost/state-balances/ajaxGdtOverview
|
|
||||||
create: async (sessionId, email, amount, memo, target_date = new Date() ) => {
|
|
||||||
const payload = {
|
|
||||||
sessionId,
|
|
||||||
email,
|
|
||||||
amount,
|
|
||||||
target_date,
|
|
||||||
memo,
|
|
||||||
auto_sign: true,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.COMMUNITY_API__URL + 'createCoins/', payload)
|
|
||||||
}, */
|
|
||||||
send: async (sessionId, data) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
auto_sign: true,
|
|
||||||
...data,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.COMMUNITY_API_URL + 'sendCoins/', payload)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default communityAPI
|
|
||||||
@ -1,145 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import CONFIG from '../config'
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
import regeneratorRuntime from 'regenerator-runtime'
|
|
||||||
|
|
||||||
// control email-text sended with email verification code
|
|
||||||
const EMAIL_TYPE = {
|
|
||||||
DEFAULT: 2, // if user has registered directly
|
|
||||||
ADMIN: 5, // if user was registered by an admin
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiGet = async (url) => {
|
|
||||||
try {
|
|
||||||
const result = await axios.get(url)
|
|
||||||
if (result.status !== 200) {
|
|
||||||
throw new Error('HTTP Status Error ' + result.status)
|
|
||||||
}
|
|
||||||
if (!['success', 'warning'].includes(result.data.state)) {
|
|
||||||
throw new Error(result.data.msg)
|
|
||||||
}
|
|
||||||
return { success: true, result }
|
|
||||||
} catch (error) {
|
|
||||||
return { success: false, result: error }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiPost = async (url, payload) => {
|
|
||||||
try {
|
|
||||||
const result = await axios.post(url, payload)
|
|
||||||
if (result.status !== 200) {
|
|
||||||
throw new Error('HTTP Status Error ' + result.status)
|
|
||||||
}
|
|
||||||
if (result.data.state === 'warning') {
|
|
||||||
return { success: true, result: result.error }
|
|
||||||
}
|
|
||||||
if (result.data.state !== 'success') {
|
|
||||||
throw new Error(result.data.msg)
|
|
||||||
}
|
|
||||||
return { success: true, result }
|
|
||||||
} catch (error) {
|
|
||||||
return { success: false, result: error }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginAPI = {
|
|
||||||
login: async (email, password) => {
|
|
||||||
const payload = {
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', payload)
|
|
||||||
},
|
|
||||||
logout: async (sessionId) => {
|
|
||||||
const payload = { session_id: sessionId }
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'logout', payload)
|
|
||||||
},
|
|
||||||
create: async (email, firstName, lastName, password) => {
|
|
||||||
const payload = {
|
|
||||||
email,
|
|
||||||
first_name: firstName,
|
|
||||||
last_name: lastName,
|
|
||||||
password,
|
|
||||||
emailType: EMAIL_TYPE.DEFAULT,
|
|
||||||
login_after_register: true,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload)
|
|
||||||
},
|
|
||||||
sendEmail: async (email, email_text = 7, email_verification_code_type = 'resetPassword') => {
|
|
||||||
const payload = {
|
|
||||||
email,
|
|
||||||
email_text,
|
|
||||||
email_verification_code_type,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'sendEmail', payload)
|
|
||||||
},
|
|
||||||
loginViaEmailVerificationCode: async (optin) => {
|
|
||||||
return apiGet(
|
|
||||||
CONFIG.LOGIN_API_URL + 'loginViaEmailVerificationCode?emailVerificationCode=' + optin,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
getUserInfos: async (sessionId, email) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email: email,
|
|
||||||
ask: ['user.first_name', 'user.last_name'],
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'getUserInfos', payload)
|
|
||||||
},
|
|
||||||
updateUserInfos: async (sessionId, email, data) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email,
|
|
||||||
update: {
|
|
||||||
'User.first_name': data.firstName,
|
|
||||||
'User.last_name': data.lastName,
|
|
||||||
// 'User.description': data.description,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
|
||||||
},
|
|
||||||
changePassword: async (sessionId, email, password) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'resetPassword', payload)
|
|
||||||
},
|
|
||||||
changePasswordProfile: async (sessionId, email, password, passwordNew) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email,
|
|
||||||
update: {
|
|
||||||
'User.password_old': password,
|
|
||||||
'User.password': passwordNew,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
|
||||||
},
|
|
||||||
changeUsernameProfile: async (sessionId, email, username) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email,
|
|
||||||
update: {
|
|
||||||
'User.username': username,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
|
||||||
},
|
|
||||||
updateLanguage: async (sessionId, email, language) => {
|
|
||||||
const payload = {
|
|
||||||
session_id: sessionId,
|
|
||||||
email,
|
|
||||||
update: {
|
|
||||||
'User.language': language,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
|
||||||
},
|
|
||||||
checkUsername: async (username, groupId = 1) => {
|
|
||||||
return apiGet(CONFIG.LOGIN_API_URL + `checkUsername?username=${username}&group_id=${groupId}`)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default loginAPI
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<div v-if="decaytyp === 'new'">
|
<div v-if="decaytyp === 'new'">
|
||||||
<b-list-group style="border: 0px">
|
<b-list-group style="border: 0px">
|
||||||
<b-list-group-item style="border: 0px; background-color: #f1f1f1">
|
<b-list-group-item style="border: 0px; background-color: #f1f1f1">
|
||||||
<div class="d-flex" v-if="!decay.decay_start_block">
|
<div class="d-flex" v-if="!decay.decayStartBlock">
|
||||||
<div style="width: 100%" class="text-center pb-3">
|
<div style="width: 100%" class="text-center pb-3">
|
||||||
<b-icon icon="droplet-half" height="12" class="mb-2" />
|
<b-icon icon="droplet-half" height="12" class="mb-2" />
|
||||||
<b>{{ $t('decay.calculation_decay') }}</b>
|
<b>{{ $t('decay.calculation_decay') }}</b>
|
||||||
@ -16,19 +16,19 @@
|
|||||||
|
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div style="width: 40%" class="text-right pr-3 mr-2">
|
<div style="width: 40%" class="text-right pr-3 mr-2">
|
||||||
<div v-if="!decay.decay_start_block">{{ $t('decay.last_transaction') }}</div>
|
<div v-if="!decay.decayStartBlock">{{ $t('decay.last_transaction') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 60%">
|
<div style="width: 60%">
|
||||||
<div v-if="decay.decay_start_block">
|
<div v-if="decay.decayStartBlock > 0">
|
||||||
<div class="display-4">{{ $t('decay.Starting_block_decay') }}</div>
|
<div class="display-4">{{ $t('decay.Starting_block_decay') }}</div>
|
||||||
<div>
|
<div>
|
||||||
{{ $t('decay.decay_introduced') }} :
|
{{ $t('decay.decay_introduced') }} :
|
||||||
{{ $d($moment.unix(decay.decay_start), 'long') }}
|
{{ $d($moment.unix(decay.decayStart), 'long') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span v-if="!decay.decay_start_block">
|
<span v-if="!decay.decayStart">
|
||||||
{{ $d($moment.unix(decay.decay_start), 'long') }}
|
{{ $d($moment.unix(decay.decayStart), 'long') }}
|
||||||
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
|
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -37,10 +37,10 @@
|
|||||||
|
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div style="width: 40%" class="text-right pr-3 mr-2">
|
<div style="width: 40%" class="text-right pr-3 mr-2">
|
||||||
<div v-if="!decay.decay_start_block">{{ $t('decay.past_time') }}</div>
|
<div v-if="!decay.decayStartBlock">{{ $t('decay.past_time') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 60%">
|
<div style="width: 60%">
|
||||||
<div v-if="decay.decay_start_block">{{ $t('decay.since_introduction') }}</div>
|
<div v-if="decay.decayStartBlock > 0">{{ $t('decay.since_introduction') }}</div>
|
||||||
<span v-if="duration">
|
<span v-if="duration">
|
||||||
<span v-if="duration.years > 0">{{ duration.years }} {{ $t('decay.year') }},</span>
|
<span v-if="duration.years > 0">{{ duration.years }} {{ $t('decay.year') }},</span>
|
||||||
<span v-if="duration.months > 0">
|
<span v-if="duration.months > 0">
|
||||||
@ -68,24 +68,24 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
decay: {
|
decay: {
|
||||||
balance: '',
|
balance: '',
|
||||||
decay_duration: '',
|
decayDuration: '',
|
||||||
decay_start: 0,
|
decayStart: 0,
|
||||||
decay_end: 0,
|
decayEnd: 0,
|
||||||
decay_start_block: 0,
|
decayStartBlock: 0,
|
||||||
},
|
},
|
||||||
decaytyp: { type: String, default: '' },
|
decaytyp: { type: String, default: '' },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
decayStartBlockTextShort() {
|
decayStartBlockTextShort() {
|
||||||
return this.decay.decay_start_block
|
return this.decay.decayStartBlock
|
||||||
? this.$t('decay.decayStart') + this.$d(this.$moment.unix(this.decay.decay_start_block))
|
? this.$t('decay.decayStart') + this.$d(this.$moment.unix(this.decay.decayStartBlock))
|
||||||
: ''
|
: ''
|
||||||
},
|
},
|
||||||
duration() {
|
duration() {
|
||||||
return this.$moment.duration(
|
return this.$moment.duration(
|
||||||
this.$moment
|
this.$moment
|
||||||
.unix(new Date(this.decay.decay_end))
|
.unix(new Date(this.decay.decayEnd))
|
||||||
.diff(this.$moment.unix(new Date(this.decay.decay_start))),
|
.diff(this.$moment.unix(new Date(this.decay.decayStart))),
|
||||||
)._data
|
)._data
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,6 +3,14 @@ import LanguageSwitch from './LanguageSwitch'
|
|||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
|
const updateUserInfosQueryMock = jest.fn().mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
describe('LanguageSwitch', () => {
|
describe('LanguageSwitch', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -20,6 +28,9 @@ describe('LanguageSwitch', () => {
|
|||||||
$i18n: {
|
$i18n: {
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: updateUserInfosQueryMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
@ -37,17 +48,22 @@ describe('LanguageSwitch', () => {
|
|||||||
|
|
||||||
describe('with locales en and de', () => {
|
describe('with locales en and de', () => {
|
||||||
describe('empty store', () => {
|
describe('empty store', () => {
|
||||||
it('shows English as default navigator langauge', () => {
|
describe('navigator language is "en-US"', () => {
|
||||||
|
const languageGetter = jest.spyOn(navigator, 'language', 'get')
|
||||||
|
|
||||||
|
it('shows English as default navigator langauge', async () => {
|
||||||
|
languageGetter.mockReturnValue('en-US')
|
||||||
|
wrapper.vm.setCurrentLanguage()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en')
|
expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en')
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('navigator language is "de-DE"', () => {
|
describe('navigator language is "de-DE"', () => {
|
||||||
const mockNavigator = jest.fn(() => {
|
const languageGetter = jest.spyOn(navigator, 'language', 'get')
|
||||||
return 'de'
|
|
||||||
})
|
|
||||||
|
|
||||||
it('shows Deutsch as language ', async () => {
|
it('shows Deutsch as language ', async () => {
|
||||||
wrapper.vm.getNavigatorLanguage = mockNavigator
|
languageGetter.mockReturnValue('de-DE')
|
||||||
wrapper.vm.setCurrentLanguage()
|
wrapper.vm.setCurrentLanguage()
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.find('button.dropdown-toggle').text()).toBe('Deutsch - de')
|
expect(wrapper.find('button.dropdown-toggle').text()).toBe('Deutsch - de')
|
||||||
@ -55,12 +71,21 @@ describe('LanguageSwitch', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('navigator language is "es-ES" (not supported)', () => {
|
describe('navigator language is "es-ES" (not supported)', () => {
|
||||||
const mockNavigator = jest.fn(() => {
|
const languageGetter = jest.spyOn(navigator, 'language', 'get')
|
||||||
return 'es'
|
|
||||||
})
|
|
||||||
|
|
||||||
it('shows English as language ', async () => {
|
it('shows English as language ', async () => {
|
||||||
wrapper.vm.getNavigatorLanguage = mockNavigator
|
languageGetter.mockReturnValue('es-ES')
|
||||||
|
wrapper.vm.setCurrentLanguage()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('no navigator langauge', () => {
|
||||||
|
const languageGetter = jest.spyOn(navigator, 'language', 'get')
|
||||||
|
|
||||||
|
it('shows English as language ', async () => {
|
||||||
|
languageGetter.mockReturnValue(null)
|
||||||
wrapper.vm.setCurrentLanguage()
|
wrapper.vm.setCurrentLanguage()
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en')
|
expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en')
|
||||||
@ -91,5 +116,33 @@ describe('LanguageSwitch', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('calls the API', () => {
|
||||||
|
it("with locale 'en'", () => {
|
||||||
|
wrapper.findAll('li').at(0).find('a').trigger('click')
|
||||||
|
expect(updateUserInfosQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1234,
|
||||||
|
email: 'he@ho.he',
|
||||||
|
locale: 'en',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("with locale 'de'", () => {
|
||||||
|
wrapper.findAll('li').at(1).find('a').trigger('click')
|
||||||
|
expect(updateUserInfosQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1234,
|
||||||
|
email: 'he@ho.he',
|
||||||
|
locale: 'de',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { localeChanged } from 'vee-validate'
|
import { localeChanged } from 'vee-validate'
|
||||||
import locales from '../locales/'
|
import locales from '../locales/'
|
||||||
import loginAPI from '../apis/loginAPI'
|
import { updateUserInfos } from '../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LanguageSwitch',
|
name: 'LanguageSwitch',
|
||||||
@ -34,16 +34,21 @@ export default {
|
|||||||
async saveLocale(locale) {
|
async saveLocale(locale) {
|
||||||
this.setLocale(locale)
|
this.setLocale(locale)
|
||||||
if (this.$store.state.sessionId && this.$store.state.email) {
|
if (this.$store.state.sessionId && this.$store.state.email) {
|
||||||
const result = await loginAPI.updateLanguage(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
this.$store.state.email,
|
query: updateUserInfos,
|
||||||
locale,
|
variables: {
|
||||||
)
|
sessionId: this.$store.state.sessionId,
|
||||||
if (result.success) {
|
email: this.$store.state.email,
|
||||||
|
locale: locale,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
// toast success message
|
// toast success message
|
||||||
} else {
|
})
|
||||||
|
.catch(() => {
|
||||||
// toast error message
|
// toast error message
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLocaleObject(code) {
|
getLocaleObject(code) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ const environment = {
|
|||||||
const server = {
|
const server = {
|
||||||
LOGIN_API_URL: process.env.LOGIN_API_URL || 'http://localhost/login_api/',
|
LOGIN_API_URL: process.env.LOGIN_API_URL || 'http://localhost/login_api/',
|
||||||
COMMUNITY_API_URL: process.env.COMMUNITY_API_URL || 'http://localhost/api/',
|
COMMUNITY_API_URL: process.env.COMMUNITY_API_URL || 'http://localhost/api/',
|
||||||
|
GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000/graphql',
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
|
|||||||
142
frontend/src/graphql/queries.js
Normal file
142
frontend/src/graphql/queries.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
export const login = gql`
|
||||||
|
query($email: String!, $password: String!) {
|
||||||
|
login(email: $email, password: $password) {
|
||||||
|
sessionId
|
||||||
|
user {
|
||||||
|
email
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
language
|
||||||
|
username
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const logout = gql`
|
||||||
|
query($sessionId: Float!) {
|
||||||
|
logout(sessionId: $sessionId)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const resetPassword = gql`
|
||||||
|
query($sessionId: Float!, $email: String!, $password: String!) {
|
||||||
|
resetPassword(sessionId: $sessionId, email: $email, password: $password)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const loginViaEmailVerificationCode = gql`
|
||||||
|
query($optin: String!) {
|
||||||
|
loginViaEmailVerificationCode(optin: $optin) {
|
||||||
|
sessionId
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const updateUserInfos = gql`
|
||||||
|
query(
|
||||||
|
$sessionId: Float!
|
||||||
|
$email: String!
|
||||||
|
$firstName: String
|
||||||
|
$lastName: String
|
||||||
|
$description: String
|
||||||
|
$username: String
|
||||||
|
$password: String
|
||||||
|
$passwordNew: String
|
||||||
|
$locale: String
|
||||||
|
) {
|
||||||
|
updateUserInfos(
|
||||||
|
sessionId: $sessionId
|
||||||
|
email: $email
|
||||||
|
firstName: $firstName
|
||||||
|
lastName: $lastName
|
||||||
|
description: $description
|
||||||
|
username: $username
|
||||||
|
password: $password
|
||||||
|
passwordNew: $passwordNew
|
||||||
|
language: $locale
|
||||||
|
) {
|
||||||
|
validValues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const transactionsQuery = gql`
|
||||||
|
query($sessionId: Float!, $firstPage: Int = 1, $items: Int = 25, $order: String = "DESC") {
|
||||||
|
transactionList(sessionId: $sessionId, firstPage: $firstPage, items: $items, order: $order) {
|
||||||
|
gdtSum
|
||||||
|
count
|
||||||
|
balance
|
||||||
|
decay
|
||||||
|
decayDate
|
||||||
|
transactions {
|
||||||
|
type
|
||||||
|
balance
|
||||||
|
decayStart
|
||||||
|
decayEnd
|
||||||
|
decayDuration
|
||||||
|
memo
|
||||||
|
transactionId
|
||||||
|
name
|
||||||
|
email
|
||||||
|
date
|
||||||
|
decay {
|
||||||
|
balance
|
||||||
|
decayStart
|
||||||
|
decayEnd
|
||||||
|
decayDuration
|
||||||
|
decayStartBlock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const resgisterUserQuery = gql`
|
||||||
|
query($firstName: String!, $lastName: String!, $email: String!, $password: String!) {
|
||||||
|
create(email: $email, firstName: $firstName, lastName: $lastName, password: $password)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const sendCoins = gql`
|
||||||
|
query($sessionId: Float!, $email: String!, $amount: Float!, $memo: String!) {
|
||||||
|
sendCoins(sessionId: $sessionId, email: $email, amount: $amount, memo: $memo)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const sendResetPasswordEmail = gql`
|
||||||
|
query($email: String!) {
|
||||||
|
sendResetPasswordEmail(email: $email) {
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const checkUsername = gql`
|
||||||
|
query($username: String!) {
|
||||||
|
checkUsername(username: $username) {
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const listGDTEntriesQuery = gql`
|
||||||
|
query($currentPage: Int!, $pageSize: Int!, $sessionId: Float!) {
|
||||||
|
listGDTEntries(currentPage: $currentPage, pageSize: $pageSize, sessionId: $sessionId) {
|
||||||
|
count
|
||||||
|
gdtEntries {
|
||||||
|
amount
|
||||||
|
date
|
||||||
|
comment
|
||||||
|
gdtEntryType
|
||||||
|
factor
|
||||||
|
gdt
|
||||||
|
}
|
||||||
|
gdtSum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
@ -3,11 +3,22 @@ import DashboardPlugin from './plugins/dashboard-plugin'
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import i18n from './i18n.js'
|
import i18n from './i18n.js'
|
||||||
import { loadAllRules } from './validation-rules'
|
import { loadAllRules } from './validation-rules'
|
||||||
|
import ApolloClient from 'apollo-boost'
|
||||||
|
import VueApollo from 'vue-apollo'
|
||||||
|
import CONFIG from './config'
|
||||||
|
|
||||||
import { store } from './store/store'
|
import { store } from './store/store'
|
||||||
|
|
||||||
import router from './routes/router'
|
import router from './routes/router'
|
||||||
|
|
||||||
|
const apolloClient = new ApolloClient({
|
||||||
|
uri: CONFIG.GRAPHQL_URI,
|
||||||
|
})
|
||||||
|
|
||||||
|
const apolloProvider = new VueApollo({
|
||||||
|
defaultClient: apolloClient,
|
||||||
|
})
|
||||||
|
|
||||||
// plugin setup
|
// plugin setup
|
||||||
Vue.use(DashboardPlugin)
|
Vue.use(DashboardPlugin)
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
@ -28,5 +39,6 @@ new Vue({
|
|||||||
router,
|
router,
|
||||||
store,
|
store,
|
||||||
i18n,
|
i18n,
|
||||||
|
apolloProvider,
|
||||||
render: (h) => h(App),
|
render: (h) => h(App),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -25,6 +25,8 @@ import VueMoment from 'vue-moment'
|
|||||||
import Loading from 'vue-loading-overlay'
|
import Loading from 'vue-loading-overlay'
|
||||||
import 'vue-loading-overlay/dist/vue-loading.css'
|
import 'vue-loading-overlay/dist/vue-loading.css'
|
||||||
|
|
||||||
|
import VueApollo from 'vue-apollo'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
Vue.use(GlobalComponents)
|
Vue.use(GlobalComponents)
|
||||||
@ -38,6 +40,7 @@ export default {
|
|||||||
Vue.use(VueQrcode)
|
Vue.use(VueQrcode)
|
||||||
Vue.use(FlatPickr)
|
Vue.use(FlatPickr)
|
||||||
Vue.use(Loading)
|
Vue.use(Loading)
|
||||||
|
Vue.use(VueApollo)
|
||||||
Vue.use(Toasted, {
|
Vue.use(Toasted, {
|
||||||
position: 'top-center',
|
position: 'top-center',
|
||||||
duration: 5000,
|
duration: 5000,
|
||||||
|
|||||||
@ -33,8 +33,8 @@ export const actions = {
|
|||||||
commit('email', data.user.email)
|
commit('email', data.user.email)
|
||||||
commit('language', data.user.language)
|
commit('language', data.user.language)
|
||||||
commit('username', data.user.username)
|
commit('username', data.user.username)
|
||||||
commit('firstName', data.user.first_name)
|
commit('firstName', data.user.firstName)
|
||||||
commit('lastName', data.user.last_name)
|
commit('lastName', data.user.lastName)
|
||||||
commit('description', data.user.description)
|
commit('description', data.user.description)
|
||||||
},
|
},
|
||||||
logout: ({ commit, state }) => {
|
logout: ({ commit, state }) => {
|
||||||
|
|||||||
@ -72,8 +72,8 @@ describe('Vuex store', () => {
|
|||||||
email: 'someone@there.is',
|
email: 'someone@there.is',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
username: 'user',
|
username: 'user',
|
||||||
first_name: 'Peter',
|
firstName: 'Peter',
|
||||||
last_name: 'Lustig',
|
lastName: 'Lustig',
|
||||||
description: 'Nickelbrille',
|
description: 'Nickelbrille',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { configure, extend } from 'vee-validate'
|
import { configure, extend } from 'vee-validate'
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
|
import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
|
||||||
import loginAPI from './apis/loginAPI'
|
import { checkUsername } from './graphql/queries'
|
||||||
|
|
||||||
export const loadAllRules = (i18nCallback) => {
|
export const loadAllRules = (i18nCallback) => {
|
||||||
configure({
|
configure({
|
||||||
@ -51,8 +51,19 @@ export const loadAllRules = (i18nCallback) => {
|
|||||||
|
|
||||||
extend('gddUsernameUnique', {
|
extend('gddUsernameUnique', {
|
||||||
async validate(value) {
|
async validate(value) {
|
||||||
const result = await loginAPI.checkUsername(value)
|
this.$apollo
|
||||||
return result.result.data.state === 'success'
|
.query({
|
||||||
|
query: checkUsername,
|
||||||
|
variables: {
|
||||||
|
username: value,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
return result.data.checkUsername.state === 'success'
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
message: (_, values) => i18nCallback.t('form.validation.usernmae-unique', values),
|
message: (_, values) => i18nCallback.t('form.validation.usernmae-unique', values),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||||
import Vuex from 'vuex'
|
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
import DashboardLayoutGdd from './DashboardLayout_gdd'
|
import DashboardLayoutGdd from './DashboardLayout_gdd'
|
||||||
|
|
||||||
@ -7,11 +6,15 @@ jest.useFakeTimers()
|
|||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const transitionStub = () => ({
|
const storeDispatchMock = jest.fn()
|
||||||
render(h) {
|
const storeCommitMock = jest.fn()
|
||||||
return this.$options._renderChildren
|
const routerPushMock = jest.fn()
|
||||||
|
const apolloMock = jest.fn().mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
logout: 'success',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
const toasterMock = jest.fn()
|
||||||
|
|
||||||
describe('DashboardLayoutGdd', () => {
|
describe('DashboardLayoutGdd', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
@ -28,34 +31,31 @@ describe('DashboardLayoutGdd', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
$router: {
|
$router: {
|
||||||
push: jest.fn(),
|
push: routerPushMock,
|
||||||
},
|
},
|
||||||
}
|
$toasted: {
|
||||||
|
error: toasterMock,
|
||||||
const state = {
|
},
|
||||||
user: {
|
$apollo: {
|
||||||
name: 'Peter Lustig',
|
query: apolloMock,
|
||||||
balance: 2546,
|
},
|
||||||
balance_gdt: 20,
|
$store: {
|
||||||
|
state: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
},
|
||||||
|
dispatch: storeDispatchMock,
|
||||||
|
commit: storeCommitMock,
|
||||||
},
|
},
|
||||||
email: 'peter.lustig@example.org',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
RouterLink: RouterLinkStub,
|
RouterLink: RouterLinkStub,
|
||||||
FadeTransition: transitionStub(),
|
RouterView: true,
|
||||||
RouterView: transitionStub(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
|
||||||
state,
|
|
||||||
mutations: {
|
|
||||||
language: jest.fn(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(DashboardLayoutGdd, { localVue, mocks, store, stubs })
|
return mount(DashboardLayoutGdd, { localVue, mocks, stubs })
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
@ -82,7 +82,7 @@ describe('DashboardLayoutGdd', () => {
|
|||||||
navbar = wrapper.findAll('ul.navbar-nav').at(0)
|
navbar = wrapper.findAll('ul.navbar-nav').at(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has five items in the navbar', () => {
|
it('has three items in the navbar', () => {
|
||||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -99,54 +99,152 @@ describe('DashboardLayoutGdd', () => {
|
|||||||
expect(navbar.findAll('ul > a').at(1).text()).toEqual('transactions')
|
expect(navbar.findAll('ul > a').at(1).text()).toEqual('transactions')
|
||||||
})
|
})
|
||||||
|
|
||||||
// to do: get this working!
|
it('has second item "transactions" linked to transactions in navbar', async () => {
|
||||||
it.skip('has second item "transactions" linked to transactions in navbar', async () => {
|
expect(wrapper.findAll('a').at(3).attributes('href')).toBe('/transactions')
|
||||||
navbar.findAll('ul > a').at(1).trigger('click')
|
|
||||||
await flushPromises()
|
|
||||||
await jest.runAllTimers()
|
|
||||||
await flushPromises()
|
|
||||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/transactions')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has tree items in the navbar', () => {
|
it('has three items in the navbar', () => {
|
||||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has third item "My profile" in navbar', () => {
|
it('has third item "My profile" linked to profile in navbar', async () => {
|
||||||
expect(navbar.findAll('ul > a').at(2).text()).toEqual('site.navbar.my-profil')
|
expect(wrapper.findAll('a').at(5).attributes('href')).toBe('/profile')
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('has third item "My profile" linked to profile in navbar', async () => {
|
it('has a link to the members area', () => {
|
||||||
navbar.findAll('ul > a').at(2).trigger('click')
|
expect(wrapper.findAll('ul').at(2).text()).toBe('members_area')
|
||||||
|
expect(wrapper.findAll('ul').at(2).find('a').attributes('href')).toBe(
|
||||||
|
'https://elopage.com/s/gradido/sign_in?locale=en',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has a locale switch', () => {
|
||||||
|
expect(wrapper.find('div.language-switch').exists()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has a logout button', () => {
|
||||||
|
expect(wrapper.findAll('ul').at(3).text()).toBe('logout')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('logout', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.findComponent({ name: 'sidebar' }).vm.$emit('logout')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
await jest.runAllTimers()
|
})
|
||||||
|
|
||||||
|
it('calls the API', async () => {
|
||||||
|
expect(apolloMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: { sessionId: 1 },
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('dispatches logout to store', () => {
|
||||||
|
expect(storeDispatchMock).toBeCalledWith('logout')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('redirects to login page', () => {
|
||||||
|
expect(routerPushMock).toBeCalledWith('/login')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('logout fails', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
apolloMock.mockRejectedValue({
|
||||||
|
message: 'error',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('dispatches logout to store', () => {
|
||||||
|
expect(storeDispatchMock).toBeCalledWith('logout')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('redirects to login page', () => {
|
||||||
|
expect(routerPushMock).toBeCalledWith('/login')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('update balance', () => {
|
||||||
|
it('updates the amount correctelly', async () => {
|
||||||
|
await wrapper.findComponent({ ref: 'router-view' }).vm.$emit('update-balance', 5)
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
expect(wrapper.vm.balance).toBe(-5)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('has fourth item "Settigs" in navbar', () => {
|
describe('update transactions', () => {
|
||||||
// expect(navbar.findAll('ul > li').at(3).text()).toEqual('site.navbar.settings')
|
beforeEach(async () => {
|
||||||
// })
|
apolloMock.mockResolvedValue({
|
||||||
//
|
data: {
|
||||||
// it.skip('has fourth item "Settings" linked to profileedit in navbar', async () => {
|
transactionList: {
|
||||||
// navbar.findAll('ul > li > a').at(3).trigger('click')
|
gdtSum: 100,
|
||||||
// await flushPromises()
|
count: 4,
|
||||||
// await jest.runAllTimers()
|
balance: 1450,
|
||||||
// await flushPromises()
|
decay: 1250,
|
||||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profileedit')
|
transactions: ['transaction', 'transaction', 'transaction', 'transaction'],
|
||||||
// })
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await wrapper
|
||||||
|
.findComponent({ ref: 'router-view' })
|
||||||
|
.vm.$emit('update-transactions', { firstPage: 2, items: 5 })
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
// it('has fifth item "Activity" in navbar', () => {
|
it('calls the API', () => {
|
||||||
// expect(navbar.findAll('ul > li').at(4).text()).toEqual('site.navbar.activity')
|
expect(apolloMock).toBeCalledWith(
|
||||||
// })
|
expect.objectContaining({
|
||||||
//
|
variables: {
|
||||||
// it.skip('has fourth item "Activity" linked to activity in navbar', async () => {
|
sessionId: 1,
|
||||||
// navbar.findAll('ul > li > a').at(4).trigger('click')
|
firstPage: 2,
|
||||||
// await flushPromises()
|
items: 5,
|
||||||
// await jest.runAllTimers()
|
},
|
||||||
// await flushPromises()
|
}),
|
||||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/activity')
|
)
|
||||||
// })
|
})
|
||||||
|
|
||||||
|
it('updates balance', () => {
|
||||||
|
expect(wrapper.vm.balance).toBe(1250)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('updates transactions', () => {
|
||||||
|
expect(wrapper.vm.transactions).toEqual([
|
||||||
|
'transaction',
|
||||||
|
'transaction',
|
||||||
|
'transaction',
|
||||||
|
'transaction',
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('updates GDT balance', () => {
|
||||||
|
expect(wrapper.vm.GdtBalance).toBe(100)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('updates transaction count', () => {
|
||||||
|
expect(wrapper.vm.transactionCount).toBe(4)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('update transactions returns error', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
apolloMock.mockRejectedValue({
|
||||||
|
message: 'Ouch!',
|
||||||
|
})
|
||||||
|
await wrapper
|
||||||
|
.findComponent({ ref: 'router-view' })
|
||||||
|
.vm.$emit('update-transactions', { firstPage: 2, items: 5 })
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets pending to true', () => {
|
||||||
|
expect(wrapper.vm.pending).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls $toasted.error method', () => {
|
||||||
|
expect(toasterMock).toBeCalledWith('Ouch!')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -50,6 +50,7 @@
|
|||||||
<div @click="$sidebar.displaySidebar(false)">
|
<div @click="$sidebar.displaySidebar(false)">
|
||||||
<fade-transition :duration="200" origin="center top" mode="out-in">
|
<fade-transition :duration="200" origin="center top" mode="out-in">
|
||||||
<router-view
|
<router-view
|
||||||
|
ref="router-view"
|
||||||
:balance="balance"
|
:balance="balance"
|
||||||
:gdt-balance="GdtBalance"
|
:gdt-balance="GdtBalance"
|
||||||
:transactions="transactions"
|
:transactions="transactions"
|
||||||
@ -65,31 +66,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import PerfectScrollbar from 'perfect-scrollbar'
|
import { logout, transactionsQuery } from '../../graphql/queries'
|
||||||
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
|
|
||||||
import ContentFooter from './ContentFooter.vue'
|
import ContentFooter from './ContentFooter.vue'
|
||||||
import { FadeTransition } from 'vue2-transitions'
|
import { FadeTransition } from 'vue2-transitions'
|
||||||
import communityAPI from '../../apis/communityAPI'
|
|
||||||
import VueQrcode from 'vue-qrcode'
|
import VueQrcode from 'vue-qrcode'
|
||||||
|
|
||||||
function hasElement(className) {
|
|
||||||
return document.getElementsByClassName(className).length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
function initScrollbar(className) {
|
|
||||||
if (hasElement(className)) {
|
|
||||||
// eslint-disable-next-line no-new
|
|
||||||
new PerfectScrollbar(`.${className}`)
|
|
||||||
} else {
|
|
||||||
// try to init it later in case this component is loaded async
|
|
||||||
setTimeout(() => {
|
|
||||||
initScrollbar(className)
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ContentFooter,
|
ContentFooter,
|
||||||
@ -107,44 +88,55 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initScrollbar() {
|
|
||||||
const isWindows = navigator.platform.startsWith('Win')
|
|
||||||
if (isWindows) {
|
|
||||||
initScrollbar('sidenav')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async logout() {
|
async logout() {
|
||||||
await loginAPI.logout(this.$store.state.sessionId)
|
this.$apollo
|
||||||
// do we have to check success?
|
.query({
|
||||||
|
query: logout,
|
||||||
|
variables: { sessionId: this.$store.state.sessionId },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.$sidebar.displaySidebar(false)
|
this.$sidebar.displaySidebar(false)
|
||||||
this.$store.dispatch('logout')
|
this.$store.dispatch('logout')
|
||||||
this.$router.push('/login')
|
this.$router.push('/login')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$sidebar.displaySidebar(false)
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
this.$router.push('/login')
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async updateTransactions(pagination) {
|
async updateTransactions(pagination) {
|
||||||
this.pending = true
|
this.pending = true
|
||||||
const result = await communityAPI.transactions(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
pagination.firstPage,
|
query: transactionsQuery,
|
||||||
pagination.items,
|
variables: {
|
||||||
)
|
sessionId: this.$store.state.sessionId,
|
||||||
if (result.success) {
|
firstPage: pagination.firstPage,
|
||||||
this.GdtBalance = Number(result.result.data.gdtSum)
|
items: pagination.items,
|
||||||
this.transactions = result.result.data.transactions
|
},
|
||||||
this.balance = Number(result.result.data.decay)
|
fetchPolicy: 'network-only',
|
||||||
this.bookedBalance = Number(result.result.data.balance)
|
})
|
||||||
this.transactionCount = result.result.data.count
|
.then((result) => {
|
||||||
|
const {
|
||||||
|
data: { transactionList },
|
||||||
|
} = result
|
||||||
|
this.GdtBalance = Number(transactionList.gdtSum)
|
||||||
|
this.transactions = transactionList.transactions
|
||||||
|
this.balance = Number(transactionList.decay)
|
||||||
|
this.bookedBalance = Number(transactionList.balance)
|
||||||
|
this.transactionCount = transactionList.count
|
||||||
this.pending = false
|
this.pending = false
|
||||||
} else {
|
})
|
||||||
|
.catch((error) => {
|
||||||
this.pending = true
|
this.pending = true
|
||||||
this.$toasted.error(result.result.message)
|
this.$toasted.error(error.message)
|
||||||
}
|
// what to do when loading balance fails?
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updateBalance(ammount) {
|
updateBalance(ammount) {
|
||||||
this.balance -= ammount
|
this.balance -= ammount
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.initScrollbar()
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,13 +1,8 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import AccountOverview from './AccountOverview'
|
import AccountOverview from './AccountOverview'
|
||||||
import communityAPI from '../../apis/communityAPI.js'
|
|
||||||
|
|
||||||
jest.mock('../../apis/communityAPI.js')
|
|
||||||
|
|
||||||
const sendMock = jest.fn()
|
const sendMock = jest.fn()
|
||||||
sendMock.mockReturnValue({ success: true })
|
sendMock.mockResolvedValue('success')
|
||||||
|
|
||||||
communityAPI.send = sendMock
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -27,6 +22,9 @@ describe('AccountOverview', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
$n: jest.fn((n) => String(n)),
|
$n: jest.fn((n) => String(n)),
|
||||||
|
$apollo: {
|
||||||
|
query: sendMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
@ -92,11 +90,16 @@ describe('AccountOverview', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('calls the API when send-transaction is emitted', async () => {
|
it('calls the API when send-transaction is emitted', async () => {
|
||||||
expect(sendMock).toBeCalledWith(1, {
|
expect(sendMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
email: 'user@example.org',
|
email: 'user@example.org',
|
||||||
amount: 23.45,
|
amount: 23.45,
|
||||||
memo: 'Make the best of it!',
|
memo: 'Make the best of it!',
|
||||||
})
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('emits update-balance', () => {
|
it('emits update-balance', () => {
|
||||||
@ -112,7 +115,7 @@ describe('AccountOverview', () => {
|
|||||||
describe('transaction is confirmed and server response is error', () => {
|
describe('transaction is confirmed and server response is error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
sendMock.mockReturnValue({ success: false, result: { message: 'receiver not found' } })
|
sendMock.mockRejectedValue({ message: 'receiver not found' })
|
||||||
await wrapper
|
await wrapper
|
||||||
.findComponent({ name: 'TransactionConfirmation' })
|
.findComponent({ name: 'TransactionConfirmation' })
|
||||||
.vm.$emit('send-transaction')
|
.vm.$emit('send-transaction')
|
||||||
|
|||||||
@ -51,7 +51,7 @@ import GddTransactionListFooter from './AccountOverview/GddTransactionListFooter
|
|||||||
import TransactionForm from './AccountOverview/GddSend/TransactionForm.vue'
|
import TransactionForm from './AccountOverview/GddSend/TransactionForm.vue'
|
||||||
import TransactionConfirmation from './AccountOverview/GddSend/TransactionConfirmation.vue'
|
import TransactionConfirmation from './AccountOverview/GddSend/TransactionConfirmation.vue'
|
||||||
import TransactionResult from './AccountOverview/GddSend/TransactionResult.vue'
|
import TransactionResult from './AccountOverview/GddSend/TransactionResult.vue'
|
||||||
import communityAPI from '../../apis/communityAPI.js'
|
import { sendCoins } from '../../graphql/queries.js'
|
||||||
|
|
||||||
const EMPTY_TRANSACTION_DATA = {
|
const EMPTY_TRANSACTION_DATA = {
|
||||||
email: '',
|
email: '',
|
||||||
@ -104,14 +104,22 @@ export default {
|
|||||||
},
|
},
|
||||||
async sendTransaction() {
|
async sendTransaction() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
const result = await communityAPI.send(this.$store.state.sessionId, this.transactionData)
|
this.$apollo
|
||||||
if (result.success) {
|
.query({
|
||||||
|
query: sendCoins,
|
||||||
|
variables: {
|
||||||
|
sessionId: this.$store.state.sessionId,
|
||||||
|
...this.transactionData,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.error = false
|
this.error = false
|
||||||
this.$emit('update-balance', this.transactionData.amount)
|
this.$emit('update-balance', this.transactionData.amount)
|
||||||
} else {
|
})
|
||||||
this.errorResult = result.result.message
|
.catch((err) => {
|
||||||
|
this.errorResult = err.message
|
||||||
this.error = true
|
this.error = true
|
||||||
}
|
})
|
||||||
this.currentTransactionStep = 2
|
this.currentTransactionStep = 2
|
||||||
this.loading = false
|
this.loading = false
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
<div class="gdd-transaction-list">
|
<div class="gdd-transaction-list">
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<div
|
<div
|
||||||
v-for="{ decay, transaction_id, type, date, balance, name, memo } in transactions"
|
v-for="{ decay, transactionId, type, date, balance, name, memo } in transactions"
|
||||||
:key="transaction_id"
|
:key="transactionId"
|
||||||
:style="type === 'decay' ? 'background-color:#f1e0ae3d' : ''"
|
:style="type === 'decay' ? 'background-color:#f1e0ae3d' : ''"
|
||||||
>
|
>
|
||||||
<div class="list-group-item gdd-transaction-list-item" v-b-toggle="'a' + date + ''">
|
<div class="list-group-item gdd-transaction-list-item" v-b-toggle="'a' + date + ''">
|
||||||
|
|||||||
@ -6,16 +6,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
v-for="{ id, amount, date, comment, gdt_entry_type_id, factor, gdt } in transactionsGdt"
|
v-for="{
|
||||||
:key="id"
|
transactionId,
|
||||||
|
amount,
|
||||||
|
date,
|
||||||
|
comment,
|
||||||
|
gdtEntryType,
|
||||||
|
factor,
|
||||||
|
gdt,
|
||||||
|
} in transactionsGdt"
|
||||||
|
:key="transactionId"
|
||||||
>
|
>
|
||||||
<div class="list-group-item gdt-transaction-list-item" v-b-toggle="'a' + date + ''">
|
<div class="list-group-item gdt-transaction-list-item" v-b-toggle="'a' + date + ''">
|
||||||
<!-- Icon -->
|
<!-- Icon -->
|
||||||
<div class="text-right" style="position: absolute">
|
<div class="text-right" style="position: absolute">
|
||||||
<b-icon
|
<b-icon
|
||||||
v-if="gdt_entry_type_id"
|
v-if="gdtEntryType"
|
||||||
:icon="getIcon(gdt_entry_type_id).icon"
|
:icon="getIcon(gdtEntryType).icon"
|
||||||
:class="getIcon(gdt_entry_type_id).class"
|
:class="getIcon(gdtEntryType).class"
|
||||||
></b-icon>
|
></b-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -29,7 +37,7 @@
|
|||||||
<!-- Betrag -->
|
<!-- Betrag -->
|
||||||
|
|
||||||
<!-- 7 nur GDT erhalten -->
|
<!-- 7 nur GDT erhalten -->
|
||||||
<b-row v-if="gdt_entry_type_id === 7">
|
<b-row v-if="gdtEntryType === 7">
|
||||||
<div class="col-6 text-right">
|
<div class="col-6 text-right">
|
||||||
<div>{{ $t('gdt.gdt-receive') }}</div>
|
<div>{{ $t('gdt.gdt-receive') }}</div>
|
||||||
<div>{{ $t('gdt.credit') }}</div>
|
<div>{{ $t('gdt.credit') }}</div>
|
||||||
@ -40,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</b-row>
|
</b-row>
|
||||||
<!--4 publisher -->
|
<!--4 publisher -->
|
||||||
<b-row v-else-if="gdt_entry_type_id === 4">
|
<b-row v-else-if="gdtEntryType === 4">
|
||||||
<div class="col-6 text-right">
|
<div class="col-6 text-right">
|
||||||
<div>{{ $t('gdt.your-share') }}</div>
|
<div>{{ $t('gdt.your-share') }}</div>
|
||||||
<div>{{ $t('gdt.credit') }}</div>
|
<div>{{ $t('gdt.credit') }}</div>
|
||||||
@ -65,7 +73,7 @@
|
|||||||
<!-- Betrag ENDE-->
|
<!-- Betrag ENDE-->
|
||||||
|
|
||||||
<!-- Nachricht-->
|
<!-- Nachricht-->
|
||||||
<b-row v-if="comment && gdt_entry_type_id !== 7">
|
<b-row v-if="comment && gdtEntryType !== 7">
|
||||||
<div class="col-6 text-right">
|
<div class="col-6 text-right">
|
||||||
{{ $t('form.memo') }}
|
{{ $t('form.memo') }}
|
||||||
</div>
|
</div>
|
||||||
@ -87,21 +95,21 @@
|
|||||||
|
|
||||||
<!-- Collaps START -->
|
<!-- Collaps START -->
|
||||||
|
|
||||||
<b-collapse v-if="gdt_entry_type_id" :id="'a' + date + ''" class="pb-4">
|
<b-collapse v-if="gdtEntryType" :id="'a' + date + ''" class="pb-4">
|
||||||
<div style="border: 0px; background-color: #f1f1f1" class="p-2 pb-4 mb-4">
|
<div style="border: 0px; background-color: #f1f1f1" class="p-2 pb-4 mb-4">
|
||||||
<!-- Überschrift -->
|
<!-- Überschrift -->
|
||||||
<b-row class="gdt-list-clooaps-header-text text-center pb-3">
|
<b-row class="gdt-list-clooaps-header-text text-center pb-3">
|
||||||
<div class="col h4" v-if="gdt_entry_type_id === 7">
|
<div class="col h4" v-if="gdtEntryType === 7">
|
||||||
{{ $t('gdt.conversion-gdt-euro') }}
|
{{ $t('gdt.conversion-gdt-euro') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col h4" v-else-if="gdt_entry_type_id === 4">
|
<div class="col h4" v-else-if="gdtEntryType === 4">
|
||||||
{{ $t('gdt.publisher') }}
|
{{ $t('gdt.publisher') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col h4" v-else>{{ $t('gdt.calculation') }}</div>
|
<div class="col h4" v-else>{{ $t('gdt.calculation') }}</div>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
|
||||||
<!-- 7 nur GDT erhalten -->
|
<!-- 7 nur GDT erhalten -->
|
||||||
<b-row class="gdt-list-clooaps-box-7" v-if="gdt_entry_type_id == 7">
|
<b-row class="gdt-list-clooaps-box-7" v-if="gdtEntryType == 7">
|
||||||
<div class="col-6 text-right clooaps-col-left">
|
<div class="col-6 text-right clooaps-col-left">
|
||||||
<div>{{ $t('gdt.raise') }}</div>
|
<div>{{ $t('gdt.raise') }}</div>
|
||||||
<div>{{ $t('gdt.conversion') }}</div>
|
<div>{{ $t('gdt.conversion') }}</div>
|
||||||
@ -115,7 +123,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</b-row>
|
</b-row>
|
||||||
<!-- 4 publisher -->
|
<!-- 4 publisher -->
|
||||||
<b-row class="gdt-list-clooaps-box-4" v-else-if="gdt_entry_type_id === 4">
|
<b-row class="gdt-list-clooaps-box-4" v-else-if="gdtEntryType === 4">
|
||||||
<div class="col-6 text-right clooaps-col-left"></div>
|
<div class="col-6 text-right clooaps-col-left"></div>
|
||||||
<div class="col-6 clooaps-col-right"></div>
|
<div class="col-6 clooaps-col-right"></div>
|
||||||
</b-row>
|
</b-row>
|
||||||
@ -152,7 +160,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import communityAPI from '../../../apis/communityAPI'
|
import { listGDTEntriesQuery } from '../../../graphql/queries'
|
||||||
import PaginationButtons from '../../../components/PaginationButtons'
|
import PaginationButtons from '../../../components/PaginationButtons'
|
||||||
|
|
||||||
const iconsByType = {
|
const iconsByType = {
|
||||||
@ -187,17 +195,25 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async updateGdt() {
|
async updateGdt() {
|
||||||
const result = await communityAPI.transactionsgdt(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
this.currentPage,
|
query: listGDTEntriesQuery,
|
||||||
this.pageSize,
|
variables: {
|
||||||
)
|
sessionId: this.$store.state.sessionId,
|
||||||
if (result.success) {
|
currentPage: this.currentPage,
|
||||||
this.transactionsGdt = result.result.data.gdtEntries
|
pageSize: this.pageSize,
|
||||||
this.transactionGdtCount = result.result.data.count
|
},
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.then((result) => {
|
||||||
}
|
const {
|
||||||
|
data: { listGDTEntries },
|
||||||
|
} = result
|
||||||
|
this.transactionsGdt = listGDTEntries.gdtEntries
|
||||||
|
this.transactionGdtCount = listGDTEntries.count
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.$toasted.error(error.message)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
getIcon(givenType) {
|
getIcon(givenType) {
|
||||||
const type = iconsByType[givenType]
|
const type = iconsByType[givenType]
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
import loginAPI from '../../apis/loginAPI.js'
|
|
||||||
import ForgotPassword from './ForgotPassword'
|
import ForgotPassword from './ForgotPassword'
|
||||||
|
|
||||||
jest.mock('../../apis/loginAPI.js')
|
|
||||||
|
|
||||||
const mockAPIcall = jest.fn()
|
const mockAPIcall = jest.fn()
|
||||||
loginAPI.sendEmail = mockAPIcall
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -20,6 +16,9 @@ describe('ForgotPassword', () => {
|
|||||||
$router: {
|
$router: {
|
||||||
push: mockRouterPush,
|
push: mockRouterPush,
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: mockAPIcall,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
@ -92,20 +91,58 @@ describe('ForgotPassword', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('valid Email', () => {
|
describe('valid Email', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
form.find('input').setValue('user@example.org')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('calls the API', () => {
|
||||||
|
describe('sends back error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await form.find('input').setValue('user@example.org')
|
mockAPIcall.mockRejectedValue({
|
||||||
|
message: 'error',
|
||||||
|
})
|
||||||
await form.trigger('submit')
|
await form.trigger('submit')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the API', () => {
|
it('pushes to "/thx/password"', () => {
|
||||||
expect(mockAPIcall).toHaveBeenCalledWith('user@example.org')
|
expect(mockAPIcall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'user@example.org',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
expect(mockRouterPush).toHaveBeenCalledWith('/thx/password')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('pushes "/thx/password" to the route', () => {
|
describe('success', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
sendResetPasswordEmail: {
|
||||||
|
state: 'success',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await form.trigger('submit')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('pushes to "/thx/password"', () => {
|
||||||
|
expect(mockAPIcall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'user@example.org',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
expect(mockRouterPush).toHaveBeenCalledWith('/thx/password')
|
expect(mockRouterPush).toHaveBeenCalledWith('/thx/password')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../apis/loginAPI.js'
|
import { sendResetPasswordEmail } from '../../graphql/queries'
|
||||||
import InputEmail from '../../components/Inputs/InputEmail'
|
import InputEmail from '../../components/Inputs/InputEmail'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -56,9 +56,19 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
await loginAPI.sendEmail(this.form.email)
|
this.$apollo
|
||||||
// always give success to avoid email spying
|
.query({
|
||||||
|
query: sendResetPasswordEmail,
|
||||||
|
variables: {
|
||||||
|
email: this.form.email,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.$router.push('/thx/password')
|
this.$router.push('/thx/password')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$router.push('/thx/password')
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
import Login from './Login'
|
import Login from './Login'
|
||||||
|
|
||||||
jest.mock('../../apis/loginAPI')
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const mockLoginCall = jest.fn()
|
const loginQueryMock = jest.fn().mockResolvedValue({
|
||||||
mockLoginCall.mockReturnValue({
|
|
||||||
success: true,
|
|
||||||
result: {
|
|
||||||
data: {
|
data: {
|
||||||
session_id: 1,
|
login: {
|
||||||
|
sessionId: 1,
|
||||||
user: {
|
user: {
|
||||||
name: 'Peter Lustig',
|
name: 'Peter Lustig',
|
||||||
},
|
},
|
||||||
@ -20,8 +15,6 @@ mockLoginCall.mockReturnValue({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
loginAPI.login = mockLoginCall
|
|
||||||
|
|
||||||
const toastErrorMock = jest.fn()
|
const toastErrorMock = jest.fn()
|
||||||
const mockStoreDispach = jest.fn()
|
const mockStoreDispach = jest.fn()
|
||||||
const mockRouterPush = jest.fn()
|
const mockRouterPush = jest.fn()
|
||||||
@ -52,6 +45,9 @@ describe('Login', () => {
|
|||||||
$toasted: {
|
$toasted: {
|
||||||
error: toastErrorMock,
|
error: toastErrorMock,
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: loginQueryMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
@ -147,7 +143,14 @@ describe('Login', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('calls the API with the given data', () => {
|
it('calls the API with the given data', () => {
|
||||||
expect(mockLoginCall).toBeCalledWith('user@example.org', '1234')
|
expect(loginQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'user@example.org',
|
||||||
|
password: '1234',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('creates a spinner', () => {
|
it('creates a spinner', () => {
|
||||||
@ -173,7 +176,9 @@ describe('Login', () => {
|
|||||||
|
|
||||||
describe('login fails', () => {
|
describe('login fails', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockLoginCall.mockReturnValue({ success: false })
|
loginQueryMock.mockRejectedValue({
|
||||||
|
message: 'Ouch!',
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('hides the spinner', () => {
|
it('hides the spinner', () => {
|
||||||
|
|||||||
@ -55,10 +55,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
import CONFIG from '../../config'
|
import CONFIG from '../../config'
|
||||||
import InputPassword from '../../components/Inputs/InputPassword'
|
import InputPassword from '../../components/Inputs/InputPassword'
|
||||||
import InputEmail from '../../components/Inputs/InputEmail'
|
import InputEmail from '../../components/Inputs/InputEmail'
|
||||||
|
import { login } from '../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'login',
|
name: 'login',
|
||||||
@ -81,18 +81,26 @@ export default {
|
|||||||
const loader = this.$loading.show({
|
const loader = this.$loading.show({
|
||||||
container: this.$refs.submitButton,
|
container: this.$refs.submitButton,
|
||||||
})
|
})
|
||||||
const result = await loginAPI.login(this.form.email, this.form.password)
|
this.$apollo
|
||||||
if (result.success) {
|
.query({
|
||||||
this.$store.dispatch('login', {
|
query: login,
|
||||||
sessionId: result.result.data.session_id,
|
variables: {
|
||||||
user: result.result.data.user,
|
email: this.form.email,
|
||||||
|
password: this.form.password,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
.then((result) => {
|
||||||
|
const {
|
||||||
|
data: { login },
|
||||||
|
} = result
|
||||||
|
this.$store.dispatch('login', login)
|
||||||
this.$router.push('/overview')
|
this.$router.push('/overview')
|
||||||
loader.hide()
|
loader.hide()
|
||||||
} else {
|
})
|
||||||
|
.catch(() => {
|
||||||
loader.hide()
|
loader.hide()
|
||||||
this.$toasted.error(this.$t('error.no-account'))
|
this.$toasted.error(this.$t('error.no-account'))
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,9 @@ import Register from './Register'
|
|||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
|
const resgisterUserQueryMock = jest.fn()
|
||||||
|
const routerPushMock = jest.fn()
|
||||||
|
|
||||||
describe('Register', () => {
|
describe('Register', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -13,6 +16,12 @@ describe('Register', () => {
|
|||||||
locale: 'en',
|
locale: 'en',
|
||||||
},
|
},
|
||||||
$t: jest.fn((t) => t),
|
$t: jest.fn((t) => t),
|
||||||
|
$router: {
|
||||||
|
push: routerPushMock,
|
||||||
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: resgisterUserQueryMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
@ -105,6 +114,113 @@ describe('Register', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// To Do: Test lines 156-197,210-213
|
describe('resetForm', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper.find('#registerFirstname').setValue('Max')
|
||||||
|
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||||
|
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
||||||
|
wrapper.find('input[name="form.password"]').setValue('Aa123456')
|
||||||
|
wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456')
|
||||||
|
wrapper.find('input[name="site.signup.agree"]').setChecked(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resets the firstName field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('#registerFirstname').element.value).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resets the lastName field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('#registerLastname').element.value).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resets the email field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('#Email-input-field').element.value).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it.skip('resets the password field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('input[name="form.password"]').element.value).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it.skip('resets the passwordRepeat field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('input[name="form.passwordRepeat"]').element.value).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resets the firstName field after clicking the reset button', async () => {
|
||||||
|
await wrapper.find('button.ml-2').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('input[name="site.signup.agree"]').props.checked).not.toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('API calls', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper.find('#registerFirstname').setValue('Max')
|
||||||
|
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||||
|
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
||||||
|
wrapper.find('input[name="form.password"]').setValue('Aa123456')
|
||||||
|
wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('server sends back error', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
resgisterUserQueryMock.mockRejectedValue({ message: 'Ouch!' })
|
||||||
|
await wrapper.find('form').trigger('submit')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows error message', () => {
|
||||||
|
expect(wrapper.find('span.alert-text').exists()).toBeTruthy()
|
||||||
|
expect(wrapper.find('span.alert-text').text().length !== 0).toBeTruthy()
|
||||||
|
expect(wrapper.find('span.alert-text').text()).toContain('error.error!')
|
||||||
|
expect(wrapper.find('span.alert-text').text()).toContain('Ouch!')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('button to dismisses error message is present', () => {
|
||||||
|
expect(wrapper.find('button.close').exists()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('dismisses error message', async () => {
|
||||||
|
await wrapper.find('button.close').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('span.alert-text').exists()).not.toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('server sends back success', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
resgisterUserQueryMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
create: 'success',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('routes to "/thx/register"', async () => {
|
||||||
|
await wrapper.find('form').trigger('submit')
|
||||||
|
await flushPromises()
|
||||||
|
expect(resgisterUserQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'max.mustermann@gradido.net',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
password: 'Aa123456',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
expect(routerPushMock).toHaveBeenCalledWith('/thx/register')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// TODO: line 157
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -128,9 +128,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
import InputEmail from '../../components/Inputs/InputEmail.vue'
|
import InputEmail from '../../components/Inputs/InputEmail.vue'
|
||||||
import InputPasswordConfirmation from '../../components/Inputs/InputPasswordConfirmation.vue'
|
import InputPasswordConfirmation from '../../components/Inputs/InputPasswordConfirmation.vue'
|
||||||
|
import { resgisterUserQuery } from '../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { InputPasswordConfirmation, InputEmail },
|
components: { InputPasswordConfirmation, InputEmail },
|
||||||
@ -168,38 +168,35 @@ export default {
|
|||||||
},
|
},
|
||||||
agree: false,
|
agree: false,
|
||||||
}
|
}
|
||||||
|
this.form.password.password = ''
|
||||||
|
this.form.password.passwordRepeat = ''
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.observer.reset()
|
this.$refs.observer.reset()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
const result = await loginAPI.create(
|
this.$apollo
|
||||||
this.form.email,
|
.query({
|
||||||
this.form.firstname,
|
query: resgisterUserQuery,
|
||||||
this.form.lastname,
|
variables: {
|
||||||
this.form.password.password,
|
|
||||||
)
|
|
||||||
if (result.success) {
|
|
||||||
/* this.$store.dispatch('login', {
|
|
||||||
sessionId: result.result.data.session_id,
|
|
||||||
user: {
|
|
||||||
email: this.form.email,
|
email: this.form.email,
|
||||||
firstName: this.form.firstname,
|
firstName: this.form.firstname,
|
||||||
lastName: this.form.lastname
|
lastName: this.form.lastname,
|
||||||
}
|
password: this.form.password.password,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
*/
|
.then(() => {
|
||||||
this.form.email = ''
|
this.form.email = ''
|
||||||
this.form.firstname = ''
|
this.form.firstname = ''
|
||||||
this.form.lastname = ''
|
this.form.lastname = ''
|
||||||
this.form.password.password = ''
|
this.form.password.password = ''
|
||||||
|
this.form.password.passwordRepeat = ''
|
||||||
this.$router.push('/thx/register')
|
this.$router.push('/thx/register')
|
||||||
} else {
|
})
|
||||||
|
.catch((error) => {
|
||||||
this.showError = true
|
this.showError = true
|
||||||
this.messageError = result.result.message
|
this.messageError = error.message
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
closeAlert() {
|
closeAlert() {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
@ -208,6 +205,7 @@ export default {
|
|||||||
this.form.firstname = ''
|
this.form.firstname = ''
|
||||||
this.form.lastname = ''
|
this.form.lastname = ''
|
||||||
this.form.password.password = ''
|
this.form.password.password = ''
|
||||||
|
this.form.password.passwordRepeat = ''
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@ -1,45 +1,16 @@
|
|||||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
import ResetPassword from './ResetPassword'
|
import ResetPassword from './ResetPassword'
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
// validation is tested in src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js
|
// validation is tested in src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js
|
||||||
|
|
||||||
jest.mock('../../apis/loginAPI')
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const successResponseObject = {
|
const apolloQueryMock = jest.fn().mockRejectedValue({ message: 'error' })
|
||||||
success: true,
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
session_id: 1,
|
|
||||||
user: {
|
|
||||||
email: 'user@example.org',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const emailVerificationMock = jest.fn()
|
|
||||||
const changePasswordMock = jest.fn()
|
|
||||||
const toasterMock = jest.fn()
|
const toasterMock = jest.fn()
|
||||||
const routerPushMock = jest.fn()
|
const routerPushMock = jest.fn()
|
||||||
|
|
||||||
emailVerificationMock
|
|
||||||
.mockReturnValueOnce({ success: false, result: { message: 'error' } })
|
|
||||||
.mockReturnValueOnce({ success: false, result: { message: 'error' } })
|
|
||||||
.mockReturnValueOnce({ success: false, result: { message: 'error' } })
|
|
||||||
.mockReturnValueOnce({ success: false, result: { message: 'error' } })
|
|
||||||
.mockReturnValue(successResponseObject)
|
|
||||||
|
|
||||||
changePasswordMock
|
|
||||||
.mockReturnValueOnce({ success: false, result: { message: 'error' } })
|
|
||||||
.mockReturnValue({ success: true })
|
|
||||||
|
|
||||||
loginAPI.loginViaEmailVerificationCode = emailVerificationMock
|
|
||||||
loginAPI.changePassword = changePasswordMock
|
|
||||||
|
|
||||||
describe('ResetPassword', () => {
|
describe('ResetPassword', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -64,6 +35,9 @@ describe('ResetPassword', () => {
|
|||||||
return { hide: jest.fn() }
|
return { hide: jest.fn() }
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: apolloQueryMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
@ -79,10 +53,13 @@ describe('ResetPassword', () => {
|
|||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the email verification when created', () => {
|
it('calls the email verification when created', async () => {
|
||||||
expect(emailVerificationMock).toHaveBeenCalledWith('123')
|
expect(apolloQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({ variables: { optin: '123' } }),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('No valid optin', () => {
|
||||||
it('does not render the Reset Password form when not authenticated', () => {
|
it('does not render the Reset Password form when not authenticated', () => {
|
||||||
expect(wrapper.find('form').exists()).toBeFalsy()
|
expect(wrapper.find('form').exists()).toBeFalsy()
|
||||||
})
|
})
|
||||||
@ -95,35 +72,52 @@ describe('ResetPassword', () => {
|
|||||||
expect(wrapper.find('div.header').text()).toContain('reset-password.title')
|
expect(wrapper.find('div.header').text()).toContain('reset-password.title')
|
||||||
expect(wrapper.find('div.header').text()).toContain('reset-password.not-authenticated')
|
expect(wrapper.find('div.header').text()).toContain('reset-password.not-authenticated')
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('renders the Reset Password form when authenticated', async () => {
|
describe('is authenticated', () => {
|
||||||
await wrapper.setData({ authenticated: true })
|
beforeEach(() => {
|
||||||
|
apolloQueryMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
loginViaEmailVerificationCode: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it.skip('Has sessionId from API call', async () => {
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(wrapper.vm.sessionId).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the Reset Password form when authenticated', () => {
|
||||||
expect(wrapper.find('div.resetpwd-form').exists()).toBeTruthy()
|
expect(wrapper.find('div.resetpwd-form').exists()).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Register header', () => {
|
describe('Register header', () => {
|
||||||
it('has a welcome message', () => {
|
it('has a welcome message', async () => {
|
||||||
expect(wrapper.find('div.header').text()).toContain('reset-password.title')
|
expect(wrapper.find('div.header').text()).toContain('reset-password.title')
|
||||||
expect(wrapper.find('div.header').text()).toContain('reset-password.text')
|
expect(wrapper.find('div.header').text()).toContain('reset-password.text')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('links', () => {
|
describe('links', () => {
|
||||||
it('has a link "Back"', () => {
|
it('has a link "Back"', async () => {
|
||||||
expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toEqual('back')
|
expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toEqual('back')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('links to /login when clicking "Back"', () => {
|
it('links to /login when clicking "Back"', async () => {
|
||||||
expect(wrapper.findAllComponents(RouterLinkStub).at(0).props().to).toBe('/Login')
|
expect(wrapper.findAllComponents(RouterLinkStub).at(0).props().to).toBe('/Login')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('reset password form', () => {
|
describe('reset password form', () => {
|
||||||
it('has a register form', () => {
|
it('has a register form', async () => {
|
||||||
expect(wrapper.find('form').exists()).toBeTruthy()
|
expect(wrapper.find('form').exists()).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has 2 password input fields', () => {
|
it('has 2 password input fields', async () => {
|
||||||
expect(wrapper.findAll('input[type="password"]').length).toBe(2)
|
expect(wrapper.findAll('input[type="password"]').length).toBe(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -142,6 +136,8 @@ describe('ResetPassword', () => {
|
|||||||
|
|
||||||
describe('submit form', () => {
|
describe('submit form', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
await wrapper.setData({ authenticated: true, sessionId: 1 })
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
await wrapper.findAll('input').at(0).setValue('Aa123456')
|
await wrapper.findAll('input').at(0).setValue('Aa123456')
|
||||||
await wrapper.findAll('input').at(1).setValue('Aa123456')
|
await wrapper.findAll('input').at(1).setValue('Aa123456')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
@ -149,14 +145,32 @@ describe('ResetPassword', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('server response with error', () => {
|
describe('server response with error', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
apolloQueryMock.mockRejectedValue({ message: 'error' })
|
||||||
|
})
|
||||||
it('toasts an error message', () => {
|
it('toasts an error message', () => {
|
||||||
expect(toasterMock).toHaveBeenCalledWith('error')
|
expect(toasterMock).toHaveBeenCalledWith('error')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('server response with success', () => {
|
describe('server response with success', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
apolloQueryMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
resetPassword: 'success',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
it('calls the API', () => {
|
it('calls the API', () => {
|
||||||
expect(changePasswordMock).toHaveBeenCalledWith(1, 'user@example.org', 'Aa123456')
|
expect(apolloQueryMock).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
password: 'Aa123456',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('redirects to "/thx/reset"', () => {
|
it('redirects to "/thx/reset"', () => {
|
||||||
@ -166,3 +180,4 @@ describe('ResetPassword', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -47,8 +47,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../apis/loginAPI'
|
|
||||||
import InputPasswordConfirmation from '../../components/Inputs/InputPasswordConfirmation'
|
import InputPasswordConfirmation from '../../components/Inputs/InputPasswordConfirmation'
|
||||||
|
import { resetPassword, loginViaEmailVerificationCode } from '../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ResetPassword',
|
name: 'ResetPassword',
|
||||||
@ -70,33 +70,43 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
const result = await loginAPI.changePassword(this.sessionId, this.email, this.form.password)
|
this.$apollo
|
||||||
if (result.success) {
|
.query({
|
||||||
this.form.password = ''
|
query: resetPassword,
|
||||||
/*
|
variables: {
|
||||||
this.$store.dispatch('login', {
|
sessionId: this.sessionId,
|
||||||
sessionId: result.result.data.session_id,
|
email: this.email,
|
||||||
email: result.result.data.user.email,
|
password: this.form.password,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
*/
|
.then(() => {
|
||||||
|
this.form.password = ''
|
||||||
this.$router.push('/thx/reset')
|
this.$router.push('/thx/reset')
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.catch((error) => {
|
||||||
}
|
this.$toasted.error(error.message)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async authenticate() {
|
async authenticate() {
|
||||||
const loader = this.$loading.show({
|
const loader = this.$loading.show({
|
||||||
container: this.$refs.header,
|
container: this.$refs.header,
|
||||||
})
|
})
|
||||||
const optin = this.$route.params.optin
|
const optin = this.$route.params.optin
|
||||||
const result = await loginAPI.loginViaEmailVerificationCode(optin)
|
this.$apollo
|
||||||
if (result.success) {
|
.query({
|
||||||
|
query: loginViaEmailVerificationCode,
|
||||||
|
variables: {
|
||||||
|
optin: optin,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
this.authenticated = true
|
this.authenticated = true
|
||||||
this.sessionId = result.result.data.session_id
|
this.sessionId = result.data.loginViaEmailVerificationCode.sessionId
|
||||||
this.email = result.result.data.user.email
|
this.email = result.data.loginViaEmailVerificationCode.email
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.catch((error) => {
|
||||||
}
|
this.$toasted.error(error.message)
|
||||||
|
})
|
||||||
loader.hide()
|
loader.hide()
|
||||||
this.pending = false
|
this.pending = false
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,23 +1,16 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import UserCardFormUserData from './UserCard_FormUserData'
|
import UserCardFormUserData from './UserCard_FormUserData'
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
jest.mock('../../../apis/loginAPI')
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const mockAPIcall = jest.fn((args) => {
|
const mockAPIcall = jest.fn()
|
||||||
return { success: true }
|
|
||||||
})
|
|
||||||
|
|
||||||
const toastErrorMock = jest.fn()
|
const toastErrorMock = jest.fn()
|
||||||
const toastSuccessMock = jest.fn()
|
const toastSuccessMock = jest.fn()
|
||||||
const storeCommitMock = jest.fn()
|
const storeCommitMock = jest.fn()
|
||||||
|
|
||||||
loginAPI.updateUserInfos = mockAPIcall
|
describe('UserCard_FormUserData', () => {
|
||||||
|
|
||||||
describe('UserCard_FormUsername', () => {
|
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
@ -36,6 +29,9 @@ describe('UserCard_FormUsername', () => {
|
|||||||
success: toastSuccessMock,
|
success: toastSuccessMock,
|
||||||
error: toastErrorMock,
|
error: toastErrorMock,
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: mockAPIcall,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
@ -102,6 +98,13 @@ describe('UserCard_FormUsername', () => {
|
|||||||
|
|
||||||
describe('successfull submit', () => {
|
describe('successfull submit', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
await wrapper.findAll('input').at(0).setValue('Petra')
|
await wrapper.findAll('input').at(0).setValue('Petra')
|
||||||
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
||||||
@ -111,12 +114,18 @@ describe('UserCard_FormUsername', () => {
|
|||||||
await flushPromises()
|
await flushPromises()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the loginAPI', () => {
|
it('calls the API', () => {
|
||||||
expect(mockAPIcall).toBeCalledWith(1, 'user@example.org', {
|
expect(mockAPIcall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
firstName: 'Petra',
|
firstName: 'Petra',
|
||||||
lastName: 'Lustiger',
|
lastName: 'Lustiger',
|
||||||
description: 'Keine Nickelbrille',
|
description: 'Keine Nickelbrille',
|
||||||
})
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('commits firstname to store', () => {
|
it('commits firstname to store', () => {
|
||||||
@ -142,8 +151,10 @@ describe('UserCard_FormUsername', () => {
|
|||||||
|
|
||||||
describe('submit results in server error', () => {
|
describe('submit results in server error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockRejectedValue({
|
||||||
|
message: 'Error',
|
||||||
|
})
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
mockAPIcall.mockReturnValue({ success: false, result: { message: 'Error' } })
|
|
||||||
await wrapper.findAll('input').at(0).setValue('Petra')
|
await wrapper.findAll('input').at(0).setValue('Petra')
|
||||||
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
||||||
await wrapper.find('textarea').setValue('Keine Nickelbrille')
|
await wrapper.find('textarea').setValue('Keine Nickelbrille')
|
||||||
@ -152,12 +163,18 @@ describe('UserCard_FormUsername', () => {
|
|||||||
await flushPromises()
|
await flushPromises()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the loginAPI', () => {
|
it('calls the API', () => {
|
||||||
expect(mockAPIcall).toBeCalledWith(1, 'user@example.org', {
|
expect(mockAPIcall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
firstName: 'Petra',
|
firstName: 'Petra',
|
||||||
lastName: 'Lustiger',
|
lastName: 'Lustiger',
|
||||||
description: 'Keine Nickelbrille',
|
description: 'Keine Nickelbrille',
|
||||||
})
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('toasts an error message', () => {
|
it('toasts an error message', () => {
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
import { updateUserInfos } from '../../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormUserData',
|
name: 'FormUserData',
|
||||||
@ -114,24 +114,27 @@ export default {
|
|||||||
},
|
},
|
||||||
async onSubmit(event) {
|
async onSubmit(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const result = await loginAPI.updateUserInfos(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
this.$store.state.email,
|
query: updateUserInfos,
|
||||||
{
|
variables: {
|
||||||
|
sessionId: this.$store.state.sessionId,
|
||||||
|
email: this.$store.state.email,
|
||||||
firstName: this.form.firstName,
|
firstName: this.form.firstName,
|
||||||
lastName: this.form.lastName,
|
lastName: this.form.lastName,
|
||||||
description: this.form.description,
|
description: this.form.description,
|
||||||
},
|
},
|
||||||
)
|
})
|
||||||
if (result.success) {
|
.then(() => {
|
||||||
this.$store.commit('firstName', this.form.firstName)
|
this.$store.commit('firstName', this.form.firstName)
|
||||||
this.$store.commit('lastName', this.form.lastName)
|
this.$store.commit('lastName', this.form.lastName)
|
||||||
this.$store.commit('description', this.form.description)
|
this.$store.commit('description', this.form.description)
|
||||||
this.showUserData = true
|
this.showUserData = true
|
||||||
this.$toasted.success(this.$t('site.profil.user-data.change-success'))
|
this.$toasted.success(this.$t('site.profil.user-data.change-success'))
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.catch((error) => {
|
||||||
}
|
this.$toasted.error(error.message)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,123 @@
|
|||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import flushPromises from 'flush-promises'
|
||||||
|
import UserCardFormUserMail from './UserCard_FormUserMail'
|
||||||
|
|
||||||
|
const localVue = global.localVue
|
||||||
|
jest.spyOn(window, 'alert').mockImplementation(() => {})
|
||||||
|
|
||||||
|
const mockAPIcall = jest.fn()
|
||||||
|
|
||||||
|
describe('UserCard_FormUserMail', () => {
|
||||||
|
let wrapper
|
||||||
|
|
||||||
|
const mocks = {
|
||||||
|
$t: jest.fn((t) => t),
|
||||||
|
$store: {
|
||||||
|
state: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
firstName: 'Peter',
|
||||||
|
lastName: 'Lustig',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: mockAPIcall,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const Wrapper = () => {
|
||||||
|
return mount(UserCardFormUserMail, { localVue, mocks })
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('mount', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = Wrapper()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the component', () => {
|
||||||
|
expect(wrapper.find('div#formusermail').exists()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the edit link', () => {
|
||||||
|
expect(wrapper.find('a[href="#formusermail"]').exists()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the E-Mail form.change', () => {
|
||||||
|
expect(wrapper.findAll('div.col').at(0).text()).toBe('E-Mail form.change')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the E-Mail', () => {
|
||||||
|
expect(wrapper.findAll('div.col').at(1).text()).toBe('E-Mail')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders the E-Mail Adress', () => {
|
||||||
|
expect(wrapper.findAll('div.col').at(2).text()).toBe('user@example.org')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('edit user data', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.find('a[href="#formusermail"]').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
await wrapper.findAll('input').at(0).setValue('test@example.org')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('error API send', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockRejectedValue({
|
||||||
|
message: 'Ouch!',
|
||||||
|
})
|
||||||
|
await wrapper.find('a[href="#formusermail"]').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sends request with filled variables to the API', async () => {
|
||||||
|
expect(mockAPIcall).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
newEmail: 'test@example.org',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error message', async () => {
|
||||||
|
expect(window.alert).toBeCalledWith('Ouch!')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('successful API send', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await wrapper.find('a[href="#formusermail"]').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sends request with filled variables to the API', async () => {
|
||||||
|
expect(mockAPIcall).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
sessionId: 1,
|
||||||
|
email: 'user@example.org',
|
||||||
|
newEmail: 'test@example.org',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sends a success message', async () => {
|
||||||
|
expect(window.alert).toBeCalledWith('changePassword success')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
import { updateUserInfos } from '../../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormUserMail',
|
name: 'FormUserMail',
|
||||||
@ -44,17 +44,21 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
// console.log(this.data)
|
this.$apollo
|
||||||
const result = await loginAPI.changeEmailProfil(
|
.query({
|
||||||
this.$store.state.sessionId,
|
query: updateUserInfos,
|
||||||
this.email,
|
variables: {
|
||||||
this.newEmail,
|
sessionId: this.$store.state.sessionId,
|
||||||
)
|
email: this.$store.state.email,
|
||||||
if (result.success) {
|
newEmail: this.newEmail,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
alert('changePassword success')
|
alert('changePassword success')
|
||||||
} else {
|
})
|
||||||
alert(result.result.message)
|
.catch((error) => {
|
||||||
}
|
alert(error.message)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,16 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import UserCardFormPasswort from './UserCard_FormUserPasswort'
|
import UserCardFormPasswort from './UserCard_FormUserPasswort'
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
jest.mock('../../../apis/loginAPI')
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const changePasswordProfileMock = jest.fn()
|
const changePasswordProfileMock = jest.fn()
|
||||||
changePasswordProfileMock.mockReturnValue({ success: true })
|
changePasswordProfileMock.mockReturnValue({ success: true })
|
||||||
|
|
||||||
loginAPI.changePasswordProfile = changePasswordProfileMock
|
|
||||||
|
|
||||||
const toastSuccessMock = jest.fn()
|
const toastSuccessMock = jest.fn()
|
||||||
const toastErrorMock = jest.fn()
|
const toastErrorMock = jest.fn()
|
||||||
|
|
||||||
describe('UserCardFormUserPasswort', () => {
|
describe('UserCard_FormUserPasswort', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
@ -30,6 +25,9 @@ describe('UserCardFormUserPasswort', () => {
|
|||||||
success: toastSuccessMock,
|
success: toastSuccessMock,
|
||||||
error: toastErrorMock,
|
error: toastErrorMock,
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: changePasswordProfileMock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
@ -159,6 +157,13 @@ describe('UserCardFormUserPasswort', () => {
|
|||||||
describe('submit', () => {
|
describe('submit', () => {
|
||||||
describe('valid data', () => {
|
describe('valid data', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
changePasswordProfileMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserData: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
await form.findAll('input').at(0).setValue('1234')
|
await form.findAll('input').at(0).setValue('1234')
|
||||||
await form.findAll('input').at(1).setValue('Aa123456')
|
await form.findAll('input').at(1).setValue('Aa123456')
|
||||||
await form.findAll('input').at(2).setValue('Aa123456')
|
await form.findAll('input').at(2).setValue('Aa123456')
|
||||||
@ -168,10 +173,14 @@ describe('UserCardFormUserPasswort', () => {
|
|||||||
|
|
||||||
it('calls the API', () => {
|
it('calls the API', () => {
|
||||||
expect(changePasswordProfileMock).toHaveBeenCalledWith(
|
expect(changePasswordProfileMock).toHaveBeenCalledWith(
|
||||||
1,
|
expect.objectContaining({
|
||||||
'user@example.org',
|
variables: {
|
||||||
'1234',
|
sessionId: 1,
|
||||||
'Aa123456',
|
email: 'user@example.org',
|
||||||
|
password: '1234',
|
||||||
|
passwordNew: 'Aa123456',
|
||||||
|
},
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -186,9 +195,8 @@ describe('UserCardFormUserPasswort', () => {
|
|||||||
|
|
||||||
describe('server response is error', () => {
|
describe('server response is error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
changePasswordProfileMock.mockReturnValue({
|
changePasswordProfileMock.mockRejectedValue({
|
||||||
success: false,
|
message: 'error',
|
||||||
result: { message: 'error' },
|
|
||||||
})
|
})
|
||||||
await form.findAll('input').at(0).setValue('1234')
|
await form.findAll('input').at(0).setValue('1234')
|
||||||
await form.findAll('input').at(1).setValue('Aa123456')
|
await form.findAll('input').at(1).setValue('Aa123456')
|
||||||
|
|||||||
@ -45,9 +45,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
|
||||||
import InputPassword from '../../../components/Inputs/InputPassword'
|
import InputPassword from '../../../components/Inputs/InputPassword'
|
||||||
import InputPasswordConfirmation from '../../../components/Inputs/InputPasswordConfirmation'
|
import InputPasswordConfirmation from '../../../components/Inputs/InputPasswordConfirmation'
|
||||||
|
import { updateUserInfos } from '../../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormUserPasswort',
|
name: 'FormUserPasswort',
|
||||||
@ -77,18 +77,23 @@ export default {
|
|||||||
this.form.passwordNewRepeat = ''
|
this.form.passwordNewRepeat = ''
|
||||||
},
|
},
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
const result = await loginAPI.changePasswordProfile(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
this.$store.state.email,
|
query: updateUserInfos,
|
||||||
this.form.password,
|
variables: {
|
||||||
this.form.newPassword.password,
|
sessionId: this.$store.state.sessionId,
|
||||||
)
|
email: this.$store.state.email,
|
||||||
if (result.success) {
|
password: this.form.password,
|
||||||
|
passwordNew: this.form.newPassword.password,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.$toasted.success(this.$t('site.thx.reset'))
|
this.$toasted.success(this.$t('site.thx.reset'))
|
||||||
this.cancelEdit()
|
this.cancelEdit()
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.catch((error) => {
|
||||||
}
|
this.$toasted.error(error.message)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,11 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import UserCardFormUsername from './UserCard_FormUsername'
|
import UserCardFormUsername from './UserCard_FormUsername'
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
import { extend } from 'vee-validate'
|
import { extend } from 'vee-validate'
|
||||||
|
|
||||||
jest.mock('../../../apis/loginAPI')
|
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const mockAPIcall = jest.fn((args) => {
|
const mockAPIcall = jest.fn()
|
||||||
return { success: true }
|
|
||||||
})
|
|
||||||
|
|
||||||
// override this rule to avoid API call
|
// override this rule to avoid API call
|
||||||
extend('gddUsernameUnique', {
|
extend('gddUsernameUnique', {
|
||||||
@ -23,8 +18,6 @@ const toastErrorMock = jest.fn()
|
|||||||
const toastSuccessMock = jest.fn()
|
const toastSuccessMock = jest.fn()
|
||||||
const storeCommitMock = jest.fn()
|
const storeCommitMock = jest.fn()
|
||||||
|
|
||||||
loginAPI.changeUsernameProfile = mockAPIcall
|
|
||||||
|
|
||||||
describe('UserCard_FormUsername', () => {
|
describe('UserCard_FormUsername', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -42,6 +35,9 @@ describe('UserCard_FormUsername', () => {
|
|||||||
success: toastSuccessMock,
|
success: toastSuccessMock,
|
||||||
error: toastErrorMock,
|
error: toastErrorMock,
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
query: mockAPIcall,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
@ -98,13 +94,28 @@ describe('UserCard_FormUsername', () => {
|
|||||||
|
|
||||||
describe('successfull submit', () => {
|
describe('successfull submit', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockAPIcall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
await wrapper.find('input[placeholder="Username"]').setValue('username')
|
await wrapper.find('input[placeholder="Username"]').setValue('username')
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the loginAPI', () => {
|
it('calls the API', () => {
|
||||||
expect(mockAPIcall).toHaveBeenCalledWith(1, 'user@example.org', 'username')
|
expect(mockAPIcall).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'user@example.org',
|
||||||
|
sessionId: 1,
|
||||||
|
username: 'username',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('displays the new username', () => {
|
it('displays the new username', () => {
|
||||||
@ -127,21 +138,28 @@ describe('UserCard_FormUsername', () => {
|
|||||||
describe('submit retruns error', () => {
|
describe('submit retruns error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
mockAPIcall.mockReturnValue({
|
mockAPIcall.mockRejectedValue({
|
||||||
success: false,
|
message: 'Ouch!',
|
||||||
result: { message: 'Error' },
|
|
||||||
})
|
})
|
||||||
await wrapper.find('input[placeholder="Username"]').setValue('username')
|
await wrapper.find('input[placeholder="Username"]').setValue('username')
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls the loginAPI', () => {
|
it('calls the API', () => {
|
||||||
expect(mockAPIcall).toHaveBeenCalledWith(1, 'user@example.org', 'username')
|
expect(mockAPIcall).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'user@example.org',
|
||||||
|
sessionId: 1,
|
||||||
|
username: 'username',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('toasts an error message', () => {
|
it('toasts an error message', () => {
|
||||||
expect(toastErrorMock).toBeCalledWith('Error')
|
expect(toastErrorMock).toBeCalledWith('Ouch!')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders an empty username', () => {
|
it('renders an empty username', () => {
|
||||||
|
|||||||
@ -67,7 +67,7 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import loginAPI from '../../../apis/loginAPI'
|
import { updateUserInfos } from '../../../graphql/queries'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormUsername',
|
name: 'FormUsername',
|
||||||
@ -86,22 +86,27 @@ export default {
|
|||||||
this.showUsername = true
|
this.showUsername = true
|
||||||
},
|
},
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
const result = await loginAPI.changeUsernameProfile(
|
this.$apollo
|
||||||
this.$store.state.sessionId,
|
.query({
|
||||||
this.$store.state.email,
|
query: updateUserInfos,
|
||||||
this.form.username,
|
variables: {
|
||||||
)
|
sessionId: this.$store.state.sessionId,
|
||||||
if (result.success) {
|
email: this.$store.state.email,
|
||||||
|
username: this.form.username,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.$store.commit('username', this.form.username)
|
this.$store.commit('username', this.form.username)
|
||||||
this.username = this.form.username
|
this.username = this.form.username
|
||||||
this.showUsername = true
|
this.showUsername = true
|
||||||
this.$toasted.success(this.$t('site.profil.user-data.change-success'))
|
this.$toasted.success(this.$t('site.profil.user-data.change-success'))
|
||||||
} else {
|
})
|
||||||
this.$toasted.error(result.result.message)
|
.catch((error) => {
|
||||||
|
this.$toasted.error(error.message)
|
||||||
this.showUsername = true
|
this.showUsername = true
|
||||||
this.username = this.$store.state.username
|
this.username = this.$store.state.username
|
||||||
this.form.username = this.$store.state.username
|
this.form.username = this.$store.state.username
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1811,6 +1811,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
|
||||||
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
|
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
|
||||||
|
|
||||||
|
"@types/node@>=6":
|
||||||
|
version "16.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.12.tgz#961e3091f263e6345d2d84afab4e047a60b4b11b"
|
||||||
|
integrity sha512-zxrTNFl9Z8boMJXs6ieqZP0wAhvkdzmHSxTlJabM16cf5G9xBc1uPRH5Bbv2omEDDiM8MzTfqTJXBf0Ba4xFWA==
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.0":
|
"@types/normalize-package-data@^2.4.0":
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
||||||
@ -1865,6 +1870,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/yargs-parser" "*"
|
"@types/yargs-parser" "*"
|
||||||
|
|
||||||
|
"@types/zen-observable@^0.8.0":
|
||||||
|
version "0.8.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3"
|
||||||
|
integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==
|
||||||
|
|
||||||
"@typescript-eslint/experimental-utils@^4.0.1":
|
"@typescript-eslint/experimental-utils@^4.0.1":
|
||||||
version "4.19.0"
|
version "4.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz#9ca379919906dc72cb0fcd817d6cb5aa2d2054c6"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz#9ca379919906dc72cb0fcd817d6cb5aa2d2054c6"
|
||||||
@ -2349,6 +2359,21 @@
|
|||||||
"@webassemblyjs/wast-parser" "1.9.0"
|
"@webassemblyjs/wast-parser" "1.9.0"
|
||||||
"@xtuc/long" "4.2.2"
|
"@xtuc/long" "4.2.2"
|
||||||
|
|
||||||
|
"@wry/context@^0.4.0":
|
||||||
|
version "0.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.4.4.tgz#e50f5fa1d6cfaabf2977d1fda5ae91717f8815f8"
|
||||||
|
integrity sha512-LrKVLove/zw6h2Md/KZyWxIkFM6AoyKp71OqpH9Hiip1csjPVoD3tPxlbQUNxEnHENks3UGgNpSBCAfq9KWuag==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" ">=6"
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
"@wry/equality@^0.1.2":
|
||||||
|
version "0.1.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790"
|
||||||
|
integrity sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
"@xtuc/ieee754@^1.2.0":
|
"@xtuc/ieee754@^1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||||
@ -2587,6 +2612,101 @@ anymatch@^3.0.3, anymatch@~3.1.1:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
|
apollo-boost@^0.4.9:
|
||||||
|
version "0.4.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.4.9.tgz#ab3ba539c2ca944e6fd156583a1b1954b17a6791"
|
||||||
|
integrity sha512-05y5BKcDaa8w47f8d81UVwKqrAjn8uKLv6QM9fNdldoNzQ+rnOHgFlnrySUZRz9QIT3vPftQkEz2UEASp1Mi5g==
|
||||||
|
dependencies:
|
||||||
|
apollo-cache "^1.3.5"
|
||||||
|
apollo-cache-inmemory "^1.6.6"
|
||||||
|
apollo-client "^2.6.10"
|
||||||
|
apollo-link "^1.0.6"
|
||||||
|
apollo-link-error "^1.0.3"
|
||||||
|
apollo-link-http "^1.3.1"
|
||||||
|
graphql-tag "^2.4.2"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
|
apollo-cache-inmemory@^1.6.6:
|
||||||
|
version "1.6.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.6.tgz#56d1f2a463a6b9db32e9fa990af16d2a008206fd"
|
||||||
|
integrity sha512-L8pToTW/+Xru2FFAhkZ1OA9q4V4nuvfoPecBM34DecAugUZEBhI2Hmpgnzq2hTKZ60LAMrlqiASm0aqAY6F8/A==
|
||||||
|
dependencies:
|
||||||
|
apollo-cache "^1.3.5"
|
||||||
|
apollo-utilities "^1.3.4"
|
||||||
|
optimism "^0.10.0"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
|
apollo-cache@1.3.5, apollo-cache@^1.3.5:
|
||||||
|
version "1.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.3.5.tgz#9dbebfc8dbe8fe7f97ba568a224bca2c5d81f461"
|
||||||
|
integrity sha512-1XoDy8kJnyWY/i/+gLTEbYLnoiVtS8y7ikBr/IfmML4Qb+CM7dEEbIUOjnY716WqmZ/UpXIxTfJsY7rMcqiCXA==
|
||||||
|
dependencies:
|
||||||
|
apollo-utilities "^1.3.4"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
|
apollo-client@^2.6.10:
|
||||||
|
version "2.6.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.6.10.tgz#86637047b51d940c8eaa771a4ce1b02df16bea6a"
|
||||||
|
integrity sha512-jiPlMTN6/5CjZpJOkGeUV0mb4zxx33uXWdj/xQCfAMkuNAC3HN7CvYDyMHHEzmcQ5GV12LszWoQ/VlxET24CtA==
|
||||||
|
dependencies:
|
||||||
|
"@types/zen-observable" "^0.8.0"
|
||||||
|
apollo-cache "1.3.5"
|
||||||
|
apollo-link "^1.0.0"
|
||||||
|
apollo-utilities "1.3.4"
|
||||||
|
symbol-observable "^1.0.2"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
zen-observable "^0.8.0"
|
||||||
|
|
||||||
|
apollo-link-error@^1.0.3:
|
||||||
|
version "1.1.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.13.tgz#c1a1bb876ffe380802c8df0506a32c33aad284cd"
|
||||||
|
integrity sha512-jAZOOahJU6bwSqb2ZyskEK1XdgUY9nkmeclCrW7Gddh1uasHVqmoYc4CKdb0/H0Y1J9lvaXKle2Wsw/Zx1AyUg==
|
||||||
|
dependencies:
|
||||||
|
apollo-link "^1.2.14"
|
||||||
|
apollo-link-http-common "^0.2.16"
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
apollo-link-http-common@^0.2.16:
|
||||||
|
version "0.2.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz#756749dafc732792c8ca0923f9a40564b7c59ecc"
|
||||||
|
integrity sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==
|
||||||
|
dependencies:
|
||||||
|
apollo-link "^1.2.14"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
apollo-link-http@^1.3.1:
|
||||||
|
version "1.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.17.tgz#499e9f1711bf694497f02c51af12d82de5d8d8ba"
|
||||||
|
integrity sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg==
|
||||||
|
dependencies:
|
||||||
|
apollo-link "^1.2.14"
|
||||||
|
apollo-link-http-common "^0.2.16"
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
|
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.14:
|
||||||
|
version "1.2.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9"
|
||||||
|
integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==
|
||||||
|
dependencies:
|
||||||
|
apollo-utilities "^1.3.0"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.9.3"
|
||||||
|
zen-observable-ts "^0.8.21"
|
||||||
|
|
||||||
|
apollo-utilities@1.3.4, apollo-utilities@^1.3.0, apollo-utilities@^1.3.4:
|
||||||
|
version "1.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.4.tgz#6129e438e8be201b6c55b0f13ce49d2c7175c9cf"
|
||||||
|
integrity sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==
|
||||||
|
dependencies:
|
||||||
|
"@wry/equality" "^0.1.2"
|
||||||
|
fast-json-stable-stringify "^2.0.0"
|
||||||
|
ts-invariant "^0.4.0"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
aproba@^1.0.3, aproba@^1.1.1:
|
aproba@^1.0.3, aproba@^1.1.1:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||||
@ -6796,6 +6916,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
|
|||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||||
|
|
||||||
|
graphql-tag@^2.4.2:
|
||||||
|
version "2.12.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f"
|
||||||
|
integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.1.0"
|
||||||
|
|
||||||
|
graphql@^15.5.1:
|
||||||
|
version "15.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad"
|
||||||
|
integrity sha512-FeTRX67T3LoE3LWAxxOlW2K3Bz+rMYAC18rRguK4wgXaTZMiJwSUwDmPFo3UadAKbzirKIg5Qy+sNJXbpPRnQw==
|
||||||
|
|
||||||
growly@^1.3.0:
|
growly@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||||
@ -9979,6 +10111,13 @@ opn@^5.5.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-wsl "^1.1.0"
|
is-wsl "^1.1.0"
|
||||||
|
|
||||||
|
optimism@^0.10.0:
|
||||||
|
version "0.10.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.10.3.tgz#163268fdc741dea2fb50f300bedda80356445fd7"
|
||||||
|
integrity sha512-9A5pqGoQk49H6Vhjb9kPgAeeECfUDF6aIICbMDL23kDLStBn1MWk3YvcZ4xWF9CsSf6XEgvRLkXy4xof/56vVw==
|
||||||
|
dependencies:
|
||||||
|
"@wry/context" "^0.4.0"
|
||||||
|
|
||||||
optimist@0.3:
|
optimist@0.3:
|
||||||
version "0.3.7"
|
version "0.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9"
|
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9"
|
||||||
@ -12548,6 +12687,11 @@ sweetalert2@^9.5.4:
|
|||||||
resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-9.17.2.tgz#7f33ce157a64c303d2ca98863c9a3f437e5f1187"
|
resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-9.17.2.tgz#7f33ce157a64c303d2ca98863c9a3f437e5f1187"
|
||||||
integrity sha512-HkpPZVMYsnhFUBLdy/LvkU9snggKP3VAuSVnPhVXjxdg02lWbFx0W8H3m7A+WMWw2diXZS1wIa4m67XkNxdvew==
|
integrity sha512-HkpPZVMYsnhFUBLdy/LvkU9snggKP3VAuSVnPhVXjxdg02lWbFx0W8H3m7A+WMWw2diXZS1wIa4m67XkNxdvew==
|
||||||
|
|
||||||
|
symbol-observable@^1.0.2:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||||
|
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
|
||||||
|
|
||||||
symbol-tree@^3.2.2, symbol-tree@^3.2.4:
|
symbol-tree@^3.2.2, symbol-tree@^3.2.4:
|
||||||
version "3.2.4"
|
version "3.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||||
@ -12680,6 +12824,11 @@ throat@^5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
||||||
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
|
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
|
||||||
|
|
||||||
|
throttle-debounce@^2.1.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
|
||||||
|
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
|
||||||
|
|
||||||
through2@^2.0.0, through2@~2.0.3:
|
through2@^2.0.0, through2@~2.0.3:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
|
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
|
||||||
@ -12853,6 +13002,13 @@ tryer@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||||
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
||||||
|
|
||||||
|
ts-invariant@^0.4.0:
|
||||||
|
version "0.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86"
|
||||||
|
integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.3"
|
||||||
|
|
||||||
ts-jest@^24.2.0:
|
ts-jest@^24.2.0:
|
||||||
version "24.3.0"
|
version "24.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869"
|
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869"
|
||||||
@ -12889,11 +13045,16 @@ tsconfig@^7.0.0:
|
|||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
strip-json-comments "^2.0.0"
|
strip-json-comments "^2.0.0"
|
||||||
|
|
||||||
tslib@^1.8.1, tslib@^1.9.0:
|
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
|
tslib@^2.1.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||||
|
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||||
|
|
||||||
tsutils@^3.17.1:
|
tsutils@^3.17.1:
|
||||||
version "3.21.0"
|
version "3.21.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||||
@ -13268,6 +13429,15 @@ vm-browserify@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||||
|
|
||||||
|
vue-apollo@^3.0.7:
|
||||||
|
version "3.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.7.tgz#97a031d45641faa4888a6d5a7f71c40834359704"
|
||||||
|
integrity sha512-EUfIn4cJmoflnDJiSNP8gH4fofIEzd0I2AWnd9nhHB8mddmzIfgSNjIRihDcRB10wypYG1OG0GcU335CFgZRfA==
|
||||||
|
dependencies:
|
||||||
|
chalk "^2.4.2"
|
||||||
|
serialize-javascript "^4.0.0"
|
||||||
|
throttle-debounce "^2.1.0"
|
||||||
|
|
||||||
vue-bootstrap-typeahead@^0.2.6:
|
vue-bootstrap-typeahead@^0.2.6:
|
||||||
version "0.2.6"
|
version "0.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/vue-bootstrap-typeahead/-/vue-bootstrap-typeahead-0.2.6.tgz#8c1999a00bf4bf9fc906bae3a462482482cbc297"
|
resolved "https://registry.yarnpkg.com/vue-bootstrap-typeahead/-/vue-bootstrap-typeahead-0.2.6.tgz#8c1999a00bf4bf9fc906bae3a462482482cbc297"
|
||||||
@ -14019,3 +14189,16 @@ yorkie@^2.0.0:
|
|||||||
is-ci "^1.0.10"
|
is-ci "^1.0.10"
|
||||||
normalize-path "^1.0.0"
|
normalize-path "^1.0.0"
|
||||||
strip-indent "^2.0.0"
|
strip-indent "^2.0.0"
|
||||||
|
|
||||||
|
zen-observable-ts@^0.8.21:
|
||||||
|
version "0.8.21"
|
||||||
|
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d"
|
||||||
|
integrity sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.3"
|
||||||
|
zen-observable "^0.8.0"
|
||||||
|
|
||||||
|
zen-observable@^0.8.0:
|
||||||
|
version "0.8.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
|
||||||
|
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user