diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js index f8575492a..b8aaba502 100644 --- a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js @@ -9,50 +9,120 @@ describe('ContributionMessagesListItem', () => { const mocks = { $t: jest.fn((t) => t), $d: jest.fn((d) => d), - $store: { - state: { - moderator: { - id: 107, - }, + } + + describe('if message author has moderator role', () => { + const propsData = { + contributionId: 42, + state: 'PENDING', + message: { + id: 111, + message: 'Lorem ipsum?', + createdAt: '2022-08-29T12:23:27.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Peter', + userLastName: 'Lustig', + userId: 107, + isModerator: true, + __typename: 'ContributionMessage', }, - }, - } + } - const propsData = { - contributionId: 42, - state: 'PENDING', - message: { - id: 111, - message: 'asd asda sda sda', - createdAt: '2022-08-29T12:23:27.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Peter', - userLastName: 'Lustig', - userId: 107, - __typename: 'ContributionMessage', - }, - } + const ModeratorItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } - const Wrapper = () => { - return mount(ContributionMessagesListItem, { - localVue, - mocks, - propsData, + describe('mount', () => { + beforeAll(() => { + wrapper = ModeratorItemWrapper() + }) + + it('has a DIV .text-right.is-moderator', () => { + expect(wrapper.find('div.text-right.is-moderator').exists()).toBe(true) + }) + + it('has the complete user name', () => { + expect(wrapper.find('div.text-right.is-moderator > span:nth-child(2)').text()).toBe( + 'Peter Lustig', + ) + }) + + it('has the message creation date', () => { + expect(wrapper.find('div.text-right.is-moderator > span:nth-child(3)').text()).toMatch( + 'Mon Aug 29 2022 12:23:27 GMT+0000', + ) + }) + + it('has the moderator label', () => { + expect(wrapper.find('div.text-right.is-moderator > small:nth-child(4)').text()).toBe( + 'moderator', + ) + }) + + it('has the message', () => { + expect(wrapper.find('div.text-right.is-moderator > div:nth-child(5)').text()).toBe( + 'Lorem ipsum?', + ) + }) }) - } + }) - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) + describe('if message author does not have moderator role', () => { + const propsData = { + contributionId: 42, + state: 'PENDING', + message: { + id: 113, + message: 'Asda sdad ad asdasd, das Ass das Das. ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, + } - it('has a DIV .contribution-messages-list-item', () => { - expect(wrapper.find('div.contribution-messages-list-item').exists()).toBe(true) - }) + const ItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + describe('mount', () => { + beforeAll(() => { + wrapper = ItemWrapper() + }) + + it('has a DIV .text-left.is-not-moderator', () => { + expect(wrapper.find('div.text-left.is-not-moderator').exists()).toBe(true) + }) + + it('has the complete user name', () => { + expect(wrapper.find('div.is-not-moderator.text-left > span:nth-child(2)').text()).toBe( + 'Bibi Bloxberg', + ) + }) + + it('has the message creation date', () => { + expect(wrapper.find('div.is-not-moderator.text-left > span:nth-child(3)').text()).toMatch( + 'Mon Aug 29 2022 12:25:34 GMT+0000', + ) + }) + + it('has the message', () => { + expect(wrapper.find('div.is-not-moderator.text-left > div:nth-child(4)').text()).toBe( + 'Asda sdad ad asdasd, das Ass das Das.', + ) + }) }) }) }) diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue index fa5bdd940..796ff5f30 100644 --- a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue @@ -1,27 +1,44 @@ + diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.spec.js b/admin/src/components/ContributionMessages/slots/IsModerator.spec.js deleted file mode 100644 index b1e09da94..000000000 --- a/admin/src/components/ContributionMessages/slots/IsModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsModerator from './IsModerator.vue' - -const localVue = global.localVue - -describe('IsModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 111, - message: 'asd asda sda sda', - createdAt: '2022-08-29T12:23:27.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Peter', - userLastName: 'Lustig', - userId: 107, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-moderator', () => { - expect(wrapper.find('div.slot-is-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.vue b/admin/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index 0224e042f..000000000 --- a/admin/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js b/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js deleted file mode 100644 index 24152ad1e..000000000 --- a/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsNotModerator from './IsNotModerator.vue' - -const localVue = global.localVue - -describe('IsNotModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 113, - message: 'asda sdad ad asdasd ', - createdAt: '2022-08-29T12:25:34.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Bibi', - userLastName: 'Bloxberg', - userId: 108, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsNotModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-not-moderator', () => { - expect(wrapper.find('div.slot-is-not-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index 64946c557..000000000 --- a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/backend/log4js-config.json b/backend/log4js-config.json index 848a4fa79..e595e7c52 100644 --- a/backend/log4js-config.json +++ b/backend/log4js-config.json @@ -5,41 +5,66 @@ { "type": "dateFile", "filename": "../logs/backend/access.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "apollo": { "type": "dateFile", "filename": "../logs/backend/apollo.log", - "pattern": "%d{ISO8601} %p %c %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "backend": { "type": "dateFile", "filename": "../logs/backend/backend.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "klicktipp": { "type": "dateFile", "filename": "../logs/backend/klicktipp.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "errorFile": { "type": "dateFile", "filename": "../logs/backend/errors.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "errors": { @@ -52,7 +77,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" } }, "apolloOut": @@ -60,7 +85,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" } } }, diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 5ad578767..00ce1afde 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -351,7 +351,7 @@ export class UserResolver { } // add pubKey in logger-context for layout-pattern X{user} to print it in each logging message logger.addContext('user', dbUser.id) - logger.debug('login credentials valid...') + logger.debug('validation of login credentials successful...') const user = new User(dbUser, await getUserCreation(dbUser.id)) logger.debug(`user= ${JSON.stringify(user, null, 2)}`) @@ -396,6 +396,7 @@ export class UserResolver { @Args() { email, firstName, lastName, language, publisherId, redeemCode = null }: CreateUserArgs, ): Promise { + logger.addContext('user', 'unknown') logger.info( `createUser(email=${email}, firstName=${firstName}, lastName=${lastName}, language=${language}, publisherId=${publisherId}, redeemCode =${redeemCode})`, ) @@ -548,6 +549,7 @@ export class UserResolver { } await queryRunner.commitTransaction() + logger.addContext('user', dbUser.id) } catch (e) { logger.error(`error during create user with ${e}`) await queryRunner.rollbackTransaction() @@ -571,6 +573,7 @@ export class UserResolver { @Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL]) @Mutation(() => Boolean) async forgotPassword(@Arg('email') email: string): Promise { + logger.addContext('user', 'unknown') logger.info(`forgotPassword(${email})...`) email = email.trim().toLowerCase() const user = await findUserByEmail(email).catch(() => { diff --git a/backend/src/server/createServer.ts b/backend/src/server/createServer.ts index d1153cdb6..8ae4675db 100644 --- a/backend/src/server/createServer.ts +++ b/backend/src/server/createServer.ts @@ -35,6 +35,7 @@ const createServer = async ( context: any = serverContext, logger: Logger = apolloLogger, ): Promise => { + logger.addContext('user', 'unknown') logger.debug('createServer...') // open mysql connection diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js index b9f6f0029..7504854d0 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js @@ -1,29 +1,29 @@ import { mount } from '@vue/test-utils' import ContributionMessagesList from './ContributionMessagesList.vue' +import ContributionMessagesListItem from './ContributionMessagesListItem.vue' const localVue = global.localVue +let wrapper + +const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + $store: { + state: { + firstName: 'Peter', + lastName: 'Lustig', + }, + }, +} describe('ContributionMessagesList', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - $store: { - state: { - firstName: 'Peter', - lastName: 'Lustig', - }, - }, - } - const propsData = { contributionId: 42, - state: 'PENDING0', + state: 'PENDING', messages: [ { id: 111, - message: 'asd asda sda sda', + message: 'Lorem ipsum?', createdAt: '2022-08-29T12:23:27.000Z', updatedAt: null, type: 'DIALOG', @@ -32,10 +32,21 @@ describe('ContributionMessagesList', () => { userId: 107, __typename: 'ContributionMessage', }, + { + id: 113, + message: 'Asda sdad ad asdasd, das Ass das Das. ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, ], } - const Wrapper = () => { + const ListWrapper = () => { return mount(ContributionMessagesList, { localVue, mocks, @@ -45,11 +56,123 @@ describe('ContributionMessagesList', () => { describe('mount', () => { beforeEach(() => { - wrapper = Wrapper() + wrapper = ListWrapper() }) - it('has a DIV .contribution-messages-list-item', () => { - expect(wrapper.find('div.contribution-messages-list-item').exists()).toBe(true) + it('has two DIV .contribution-messages-list-item elements', () => { + expect(wrapper.findAll('div.contribution-messages-list-item').length).toBe(2) + }) + }) +}) + +describe('ContributionMessagesListItem', () => { + describe('if message author has moderator role', () => { + const propsData = { + message: { + id: 113, + message: 'Asda sdad ad asdasd, das Ass das Das. ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, + } + + const ItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeAll(() => { + wrapper = ItemWrapper() + }) + + it('has a DIV .is-moderator.text-left', () => { + expect(wrapper.find('div.is-moderator.text-left').exists()).toBe(true) + }) + + it('has the complete user name', () => { + expect(wrapper.find('div.is-moderator.text-left > span:nth-child(2)').text()).toBe( + 'Bibi Bloxberg', + ) + }) + + it('has the message creation date', () => { + expect(wrapper.find('div.is-moderator.text-left > span:nth-child(3)').text()).toMatch( + 'Mon Aug 29 2022 12:25:34 GMT+0000', + ) + }) + + it('has the moderator label', () => { + expect(wrapper.find('div.is-moderator.text-left > small:nth-child(4)').text()).toBe( + 'community.moderator', + ) + }) + + it('has the message', () => { + expect(wrapper.find('div.is-moderator.text-left > div:nth-child(5)').text()).toBe( + 'Asda sdad ad asdasd, das Ass das Das.', + ) + }) + }) + }) + + describe('if message author does not have moderator role', () => { + const propsData = { + message: { + id: 111, + message: 'Lorem ipsum?', + createdAt: '2022-08-29T12:23:27.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Peter', + userLastName: 'Lustig', + userId: 107, + __typename: 'ContributionMessage', + }, + } + + const ModeratorItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeAll(() => { + wrapper = ModeratorItemWrapper() + }) + + it('has a DIV .is-not-moderator.text-right', () => { + expect(wrapper.find('div.is-not-moderator.text-right').exists()).toBe(true) + }) + + it('has the complete user name', () => { + expect(wrapper.find('div.is-not-moderator.text-right > span:nth-child(2)').text()).toBe( + 'Peter Lustig', + ) + }) + + it('has the message creation date', () => { + expect(wrapper.find('div.is-not-moderator.text-right > span:nth-child(3)').text()).toMatch( + 'Mon Aug 29 2022 12:23:27 GMT+0000', + ) + }) + + it('has the message', () => { + expect(wrapper.find('div.is-not-moderator.text-right > div:nth-child(4)').text()).toBe( + 'Lorem ipsum?', + ) + }) }) }) }) diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue index 5fde8f825..6c2e555f2 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue @@ -1,26 +1,28 @@ - + diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js b/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js deleted file mode 100644 index b1e09da94..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsModerator from './IsModerator.vue' - -const localVue = global.localVue - -describe('IsModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 111, - message: 'asd asda sda sda', - createdAt: '2022-08-29T12:23:27.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Peter', - userLastName: 'Lustig', - userId: 107, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-moderator', () => { - expect(wrapper.find('div.slot-is-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.vue b/frontend/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index 343b92d97..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js b/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js deleted file mode 100644 index 24152ad1e..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsNotModerator from './IsNotModerator.vue' - -const localVue = global.localVue - -describe('IsNotModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 113, - message: 'asda sdad ad asdasd ', - createdAt: '2022-08-29T12:25:34.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Bibi', - userLastName: 'Bloxberg', - userId: 108, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsNotModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-not-moderator', () => { - expect(wrapper.find('div.slot-is-not-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue b/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index 8efca7270..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,36 +0,0 @@ - - -