diff --git a/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-item.e2e.component.ts b/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-item.e2e.component.ts index 7f3acb746b5fb3327e32ad1576d3969bbd58854b..153af72a3ad7cc8e45678372dc17b7124a266f1c 100644 --- a/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-item.e2e.component.ts +++ b/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-item.e2e.component.ts @@ -4,6 +4,7 @@ import { UserProfileE2EComponent } from '../user-profile/user-profile.component. export class VorgangListItemE2EComponent { private readonly locatorStatus: string = 'status-text'; + private readonly locatorPostfachStatus: string = 'postfach-status'; private readonly locatorWiedervorlageNextFrist: string = 'wiedervorlage-next-frist'; private readonly locatorWiedervorlagenList: string = 'wiedervorlagen-list-in-vorgang'; @@ -21,6 +22,10 @@ export class VorgangListItemE2EComponent { return this.getRoot().findTestElementWithClass(this.locatorStatus); } + public getPostfachStatus() { + return this.getRoot().findTestElementWithClass(this.locatorPostfachStatus); + } + public getWiedervorlageNextFrist() { return this.getRoot().findTestElementWithClass(this.locatorWiedervorlageNextFrist); } diff --git a/goofy-client/apps/goofy-e2e/src/fixtures/kommentar/kommentar.json b/goofy-client/apps/goofy-e2e/src/fixtures/kommentar/kommentar.json index 99e43ec177555457ce0641f2986e54a577c51a93..3e0833b92c89f5e1b0b878a1d15aeb436fdc15bf 100644 --- a/goofy-client/apps/goofy-e2e/src/fixtures/kommentar/kommentar.json +++ b/goofy-client/apps/goofy-e2e/src/fixtures/kommentar/kommentar.json @@ -2,7 +2,6 @@ "createdAt": { "$date": "2021-03-17T08:43:52.741Z" }, - "createdBy": "", - "createdByName": "Karl Kommentar", + "createdBy": "Karl Kommentar", "text": "Test text to test the test text test" } \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts index 8390ddd8440e61f1a4727a1b9a24d268400bb083..63ee7d0fd571d2ae8748978b8e57b100a507fe77 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts @@ -60,6 +60,12 @@ describe('PostfachMail', () => { dropCollections(); }) + describe('mail icon', () => { + it('should not be visible', () => { + notExist(vorgangList.getListItem(vorgang.name).getPostfachStatus()); + }) + }) + describe('navigate to vorgang detail', () => { it('should open vorgang detail', () => { @@ -297,6 +303,12 @@ describe('PostfachMail', () => { exist(vorgangList.getRoot()); }) }) + + describe('mail icon', () => { + it('should be visible', () => { + exist(vorgangList.getListItem(vorgang.name).getPostfachStatus()); + }) + }) }) describe('navigate to vorgang detail', () => { diff --git a/goofy-client/apps/goofy-e2e/src/model/kommentar.ts b/goofy-client/apps/goofy-e2e/src/model/kommentar.ts index 9efe8cf5188a92da9ddcae5204dc92ff20943fc6..5ce513a6c91f1a9aa4309eed0c0719b2d75b7d61 100644 --- a/goofy-client/apps/goofy-e2e/src/model/kommentar.ts +++ b/goofy-client/apps/goofy-e2e/src/model/kommentar.ts @@ -3,6 +3,5 @@ import { DateE2E } from './util'; export class KommentarE2E { createdAt: DateE2E; createdBy: string; - createdByName: string; text: string; } \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/model/vorgang.ts b/goofy-client/apps/goofy-e2e/src/model/vorgang.ts index b5f743835fd97be66dd97ce0cef564b496a0c914..4cf314d1fb695f7a27ba5b452c46797a83636974 100644 --- a/goofy-client/apps/goofy-e2e/src/model/vorgang.ts +++ b/goofy-client/apps/goofy-e2e/src/model/vorgang.ts @@ -36,6 +36,7 @@ export class VorgangE2E { kommentars: KommentarE2E[]; assignedTo: ResourceUriE2E; clientAttributes: ClientAttributesE2E; + hasPostfachNachricht: boolean; } export class EingangE2E { diff --git a/goofy-client/libs/kommentar-shared/src/lib/kommentar.model.ts b/goofy-client/libs/kommentar-shared/src/lib/kommentar.model.ts index 940a89aac893fddb11bf28bbff6b3126900d443a..f220ad1714a2a0b10e1c1169f7dc80ad74d35f89 100644 --- a/goofy-client/libs/kommentar-shared/src/lib/kommentar.model.ts +++ b/goofy-client/libs/kommentar-shared/src/lib/kommentar.model.ts @@ -3,7 +3,7 @@ import { ListResource } from '@goofy-client/tech-shared'; import { Resource } from '@ngxp/rest'; export interface Kommentar { - createdByName: string; + createdBy: string; createdAt: Date; text: string; } diff --git a/goofy-client/libs/kommentar-shared/test/kommentar.ts b/goofy-client/libs/kommentar-shared/test/kommentar.ts index 820b8d9a047e169d96891431bc41c8290a2a2210..5d45e4904fd1fd630a401e3a15a4865af3220491 100644 --- a/goofy-client/libs/kommentar-shared/test/kommentar.ts +++ b/goofy-client/libs/kommentar-shared/test/kommentar.ts @@ -8,7 +8,7 @@ export function createKommentar(): Kommentar { return { text: faker.random.words(10), createdAt: faker.date.past(), - createdByName: faker.random.words(2) + createdBy: faker.random.words(2) } } diff --git a/goofy-client/libs/ui/src/lib/assets/mail.svg b/goofy-client/libs/ui/src/lib/assets/mail.svg new file mode 100644 index 0000000000000000000000000000000000000000..2c6022a6b879ec179b07d039f3a678725d943fc2 --- /dev/null +++ b/goofy-client/libs/ui/src/lib/assets/mail.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8l8 5 8-5v10zm-8-7L4 6h16l-8 5z"/></svg> \ No newline at end of file diff --git a/goofy-client/libs/ui/src/lib/icon/icon.model.ts b/goofy-client/libs/ui/src/lib/icon/icon.model.ts index 9359ba70cc40acd1c03b99549c92591e4a315a10..de5e4870221ddbfd84ce478ac578be490900741b 100644 --- a/goofy-client/libs/ui/src/lib/icon/icon.model.ts +++ b/goofy-client/libs/ui/src/lib/icon/icon.model.ts @@ -6,5 +6,6 @@ export enum Icons { no_reply = 'no_reply', assignment_ind = 'assignment_ind', az = 'az', - nr = 'nr' + nr = 'nr', + mail = 'mail' } diff --git a/goofy-client/libs/vorgang-shared-ui/src/index.ts b/goofy-client/libs/vorgang-shared-ui/src/index.ts index d151c0ad220a42a5f018ccc31baaa506fd4a48c5..af2fd02f43797a7441a8a4a24e2941286b860349 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/index.ts +++ b/goofy-client/libs/vorgang-shared-ui/src/index.ts @@ -1,6 +1,7 @@ export * from './lib/aktenzeichen/aktenzeichen.component'; export * from './lib/vorgang-in-postfach-breadcrumb-container/vorgang-in-postfach-breadcrumb-container.component'; export * from './lib/vorgang-nummer/vorgang-nummer.component'; +export * from './lib/vorgang-postfach-status/vorgang-postfach-status.component'; export * from './lib/vorgang-search-container/vorgang-search-container.component'; export * from './lib/vorgang-shared-ui.module'; export * from './lib/vorgang-status-dot/vorgang-status-dot.component'; diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.html b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5d88b6c0d9d07abd69c2ea863e1c90c6bb15ee85 --- /dev/null +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.html @@ -0,0 +1,3 @@ +<mat-icon *ngIf="vorgang.hasPostfachNachricht === true" data-test-class="postfach-status" + svgIcon="mail"> +</mat-icon> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.scss b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.spec.ts b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..02635cfeada795d467a954afd56836416bd98586 --- /dev/null +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.spec.ts @@ -0,0 +1,60 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatIcon } from '@angular/material/icon'; +import { MatIconTestingModule } from '@angular/material/icon/testing'; +import { getElementFromFixture } from '@goofy-client/test-utils'; +import { VorgangResource } from '@goofy-client/vorgang-shared'; +import { getDataTestClassOf } from 'libs/tech-shared/test/data-test'; +import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang'; +import { VorgangPostfachStatusComponent } from './vorgang-postfach-status.component'; + + +describe('VorgangPostfachStatusComponent', () => { + let component: VorgangPostfachStatusComponent; + let fixture: ComponentFixture<VorgangPostfachStatusComponent>; + + const vorgang: VorgangResource = createVorgangResource(); + const postfachStatus: string = getDataTestClassOf('postfach-status'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + MatIcon, + VorgangPostfachStatusComponent + ], + imports: [ + MatIconTestingModule, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VorgangPostfachStatusComponent); + component = fixture.componentInstance; + component.vorgang = vorgang; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('mail icon', () => { + it('should show mail icon', () => { + component.vorgang.hasPostfachNachricht = true; + fixture.detectChanges(); + + const icon: HTMLElement = getElementFromFixture(fixture, postfachStatus); + + expect(icon).toHaveClass('mat-icon'); + }); + + it('should not show mail icon', () => { + component.vorgang.hasPostfachNachricht = false; + fixture.detectChanges(); + + const icon: HTMLElement = getElementFromFixture(fixture, postfachStatus); + + expect(icon).toBeNull(); + }); + }); +}); diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.ts b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..012bb0a3d13c2d7db58e31e5143644b4bb50591a --- /dev/null +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-postfach-status/vorgang-postfach-status.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; +import { Vorgang } from '@goofy-client/vorgang-shared'; + +@Component({ + selector: 'goofy-client-vorgang-postfach-status', + templateUrl: './vorgang-postfach-status.component.html', + styleUrls: ['./vorgang-postfach-status.component.scss'], +}) +export class VorgangPostfachStatusComponent { + + @Input() vorgang: Vorgang; + +} diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-shared-ui.module.ts b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-shared-ui.module.ts index 50344dd273dce9884047773ca65bd91d4920e8b5..e0e957351d94cc0d9a45d68134e4d358da5e4245 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-shared-ui.module.ts +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-shared-ui.module.ts @@ -14,6 +14,7 @@ import { VorgangSearchClearButtonComponent } from './vorgang-search-container/vo import { VorgangSearchComponent } from './vorgang-search-container/vorgang-search/vorgang-search.component'; import { VorgangStatusDotComponent } from './vorgang-status-dot/vorgang-status-dot.component'; import { VorgangStatusTextComponent } from './vorgang-status-text/vorgang-status-text.component'; +import { VorgangPostfachStatusComponent } from './vorgang-postfach-status/vorgang-postfach-status.component'; @NgModule({ imports: [ @@ -32,8 +33,9 @@ import { VorgangStatusTextComponent } from './vorgang-status-text/vorgang-status VorgangInPostfachBreadcrumbComponent, VorgangSearchAutocompleteOptionsContentComponent, VorgangSearchClearButtonComponent, - VorgangNummerComponent, - VorgangStatusTextComponent, + VorgangNummerComponent, + VorgangStatusTextComponent, + VorgangPostfachStatusComponent, ], exports: [ VorgangSearchContainerComponent, @@ -41,8 +43,9 @@ import { VorgangStatusTextComponent } from './vorgang-status-text/vorgang-status VorgangStatusDotComponent, VorgangInPostfachBreadcrumbContainerComponent, VorgangSearchAutocompleteOptionsContentComponent, - VorgangNummerComponent, - VorgangStatusTextComponent, - ] + VorgangNummerComponent, + VorgangStatusTextComponent, + VorgangPostfachStatusComponent, + ], }) -export class VorgangSharedUiModule { } +export class VorgangSharedUiModule {} diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-status-dot/vorgang-status-dot.component.scss b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-status-dot/vorgang-status-dot.component.scss index b2519b3f6e4bf3ded2b1b34d43bb53bf415f6337..0df7c2f9b59cd2e42dfb57c813766099e7caa073 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-status-dot/vorgang-status-dot.component.scss +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-status-dot/vorgang-status-dot.component.scss @@ -5,7 +5,7 @@ .dot { border-radius: 50%; background-color: mat.get-color-from-palette($primaryPalette); - margin: 0 29px 0 0; + margin: 0 1.75rem 0 0; flex-shrink: 0; &.angenommen, diff --git a/goofy-client/libs/vorgang-shared-ui/src/test-setup.ts b/goofy-client/libs/vorgang-shared-ui/src/test-setup.ts index 08ef82b5d5efa87cb27257314075f6a16eb7a63e..b7c436f08d81a131ccfcfcd2f828e06adadca227 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/test-setup.ts +++ b/goofy-client/libs/vorgang-shared-ui/src/test-setup.ts @@ -1,4 +1,5 @@ import 'jest-preset-angular/setup-jest'; +import '@testing-library/jest-dom'; import { getTestBed } from '@angular/core/testing'; import { diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.model.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.model.ts index 6ee0f5b6d4b32d57fb062294d80f8d50dcfa1f70..1db1c68ec2c7f427e600584865ba6d7e572586cc 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.model.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.model.ts @@ -8,7 +8,8 @@ export interface Vorgang { nummer: string, createdAt: Date, name: string, - nextFrist: Date + nextFrist: Date, + hasPostfachNachricht: boolean } export interface VorgangWithEingang extends Vorgang { diff --git a/goofy-client/libs/vorgang-shared/test/vorgang.ts b/goofy-client/libs/vorgang-shared/test/vorgang.ts index 172246d95a63e3a03298ae1443c045860a2fc94f..d7c3e238d56579346bb5bc76a15d412ca509a81c 100644 --- a/goofy-client/libs/vorgang-shared/test/vorgang.ts +++ b/goofy-client/libs/vorgang-shared/test/vorgang.ts @@ -10,7 +10,8 @@ export function createVorgang(): Vorgang { status: faker.helpers.arrayElement([VorgangStatus.NEU, VorgangStatus.ABGESCHLOSSEN, VorgangStatus.BESCHIEDEN, VorgangStatus.VERWORFEN]), aktenzeichen: faker.lorem.word(), nummer: faker.lorem.word(), - nextFrist: faker.date.future() + nextFrist: faker.date.future(), + hasPostfachNachricht: faker.datatype.boolean() } } diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html index 697b4e0098b6ad53f6533f2867d22c78dfbbf108..36c4396861b501bd5799f551fc82ed18110214be 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html @@ -10,6 +10,8 @@ class="status-text"></goofy-client-vorgang-status-text> </div> + <goofy-client-vorgang-postfach-status class="postfach-status" [vorgang]="vorgang"></goofy-client-vorgang-postfach-status> + <div class="aktenzeichen"> <mat-icon svgIcon="az"></mat-icon> <span class="ellipsis" goofy-client-aktenzeichen [vorgang]="vorgang"></span> diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.scss b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.scss index affafe14f67aeb74767a42aaccf80b0e84596db3..2904887d56a6bd56cfc8c1842ef5db296abdecc0 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.scss +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.scss @@ -4,11 +4,11 @@ .list-item { display: grid; - grid-template-columns: 50% 40% 10%; + grid-template-columns: 35% 15% 40% 10%; grid-template-areas: - "status wiedervorlagen eingang" - "name name name" - "aktenzeichen vorgang-nummer user-icon"; + "status postfach-status wiedervorlagen eingang" + "name name name name" + "aktenzeichen aktenzeichen vorgang-nummer user-icon"; row-gap: 8px; align-items: center; padding: 16px 24px; @@ -18,6 +18,11 @@ display: flex; align-items: center; } + .postfach-status { + grid-area: postfach-status; + display: flex; + align-items: center; + } .wiedervorlagen { grid-area: wiedervorlagen; white-space: nowrap; @@ -27,6 +32,7 @@ justify-self: end; display: flex; align-items: center; + white-space: nowrap; } .name { grid-area: name; @@ -48,10 +54,10 @@ } @include media('>desktop') { - grid-template-columns: 48% 30% 12% 10%; + grid-template-columns: 23% 25% 30% 12% 10%; grid-template-areas: - "status aktenzeichen eingang user-icon" - "name vorgang-nummer wiedervorlagen user-icon"; + "status postfach-status aktenzeichen eingang user-icon" + "name name vorgang-nummer wiedervorlagen user-icon"; padding: 16px 24px; .eingang { @@ -60,9 +66,9 @@ } @include media('>xxlDesktop') { - grid-template-columns: 25% 16% 16% 20% 10% 10% 3%; + grid-template-columns: 15% 10% 16% 16% 20% 10% 10% 3%; grid-template-areas: - "status aktenzeichen vorgang-nummer name wiedervorlagen eingang user-icon"; + "status postfach-status aktenzeichen vorgang-nummer name wiedervorlagen eingang user-icon"; .name { margin-right: 24px; diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts index 085eb75e3eb8fabdbe41e9d95772b4a9baf9cfb2..2140033efe67d131e597170a758e63a390428ebf 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts @@ -11,7 +11,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { convertForDataTest, ConvertForDataTestPipe, EnumToLabelPipe, FormatDateWithTimePipe, FormatToPrettyDatePipe, HasLinkPipe, ToResourceUriPipe } from '@goofy-client/tech-shared'; import { UserProfileInVorgangListItemContainerComponent } from '@goofy-client/user-profile'; import { VorgangHeaderLinkRel } from '@goofy-client/vorgang-shared'; -import { AktenzeichenComponent, VorgangNummerComponent, VorgangStatusDotComponent, VorgangStatusTextComponent } from '@goofy-client/vorgang-shared-ui'; +import { AktenzeichenComponent, VorgangNummerComponent, VorgangPostfachStatusComponent, VorgangStatusDotComponent, VorgangStatusTextComponent } from '@goofy-client/vorgang-shared-ui'; import { WiedervorlageListInVorgangListContainerComponent } from '@goofy-client/wiedervorlage'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang'; @@ -45,6 +45,7 @@ describe('VorgangListItemComponent', () => { ConvertForDataTestPipe, MockComponent(AktenzeichenComponent), MockComponent(VorgangNummerComponent), + MockComponent(VorgangPostfachStatusComponent), MockComponent(VorgangStatusDotComponent), MockComponent(VorgangStatusTextComponent), MockComponent(WiedervorlageListInVorgangListContainerComponent), diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java index b3c47e8af27ec615e88062f22399c48dbf7563e4..f8e2c4cf1f1bde9745c1a9bac2a2caf4b595777e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java @@ -3,6 +3,7 @@ package de.itvsh.goofy.common.command; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import de.itvsh.goofy.kommentar.Kommentar; import de.itvsh.goofy.postfach.PostfachMail; import de.itvsh.goofy.vorgang.AssignUserCommandBody; import de.itvsh.goofy.vorgang.RedirectRequest; @@ -12,7 +13,8 @@ import de.itvsh.goofy.wiedervorlage.Wiedervorlage; @Type(value = PostfachMail.class, name = "SEND_POSTFACH_MAIL"), @Type(value = AssignUserCommandBody.class, name = "ASSIGN_USER"), @Type(value = RedirectRequest.class, name = "REDIRECT_VORGANG"), - @Type(value = Wiedervorlage.class, name = "WIEDERVORLAGE") + @Type(value = Wiedervorlage.class, name = "WIEDERVORLAGE"), + @Type(value = Kommentar.class, name = "KOMMENTAR") }) public interface CommandBody { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java index dfb37d8f12b20ba1ae0ebc65d7b16f332fb79612..136cf4ea625bb8e60c4cdb2e07b0da5ae29551ab 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java @@ -15,13 +15,13 @@ public enum CommandOrder { VORGANG_ZURUECKSTELLEN(true, Type.VORGANG), VORGANG_ABSCHLIESSEN(true, Type.VORGANG), VORGANG_WIEDEREROEFFNEN(true, Type.VORGANG), - // + ASSIGN_USER(false, Type.VORGANG), - // + REDIRECT_VORGANG(false, Type.FORWARDING), FORWARD_SUCCESSFULL(false, Type.FORWARDING), FORWARD_FAILED(false, Type.FORWARDING), - // + CREATE_KOMMENTAR(false, Type.KOMMENTAR), EDIT_KOMMENTAR(false, Type.KOMMENTAR), diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java index 078b94223b11cfe8d625f8c7ae20a27127921a32..89eb1615fb6c468455689c949429c01e664907e6 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import de.itvsh.goofy.common.LinkedResource; +import de.itvsh.goofy.common.command.CommandBody; import de.itvsh.goofy.common.user.UserProfileController; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -25,17 +26,18 @@ import lombok.ToString; @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PACKAGE) @ToString -public class Kommentar { +public class Kommentar implements CommandBody { @JsonIgnore private String id; + @JsonIgnore + private String vorgangId; + @JsonProperty(access = Access.READ_ONLY) @LinkedResource(controllerClass = UserProfileController.class) private String createdBy; @JsonProperty(access = Access.READ_ONLY) - private String createdByName; - @JsonProperty(access = Access.READ_ONLY) private ZonedDateTime createdAt; @NotNull(message = FIELD_IS_EMPTY) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java index 764eead15d4c09eb1918a9ab6b2f7309554b6d14..b9040667714e68b01695b0ee0290d02d29e6b3cf 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java @@ -2,6 +2,8 @@ package de.itvsh.goofy.kommentar; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; +import java.time.ZonedDateTime; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; @@ -10,26 +12,50 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import de.itvsh.goofy.common.command.Command; import de.itvsh.goofy.common.command.CommandController; +import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; +import de.itvsh.goofy.common.command.CommandOrder; +import de.itvsh.goofy.common.command.CreateCommand; +import de.itvsh.goofy.common.user.CurrentUserService; @RestController @RequestMapping(KommentarCommandController.KOMMENTAR_COMMANDS) public class KommentarCommandController { static final String KOMMENTAR_COMMANDS = "/api/kommentars/{kommentarId}/commands"; + static final String NOT_SET = "-1"; @Autowired private KommentarService service; + @Autowired + private CommandByRelationController commandByRelationController; + @PostMapping - public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand command, @PathVariable String kommentarId) { - return buildResponseLink(service.createCommand(kommentarId, command)); + public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand kommentarCommand, @PathVariable String kommentarId) { + var command = commandByRelationController.createCommand(buildCommand(service.getById(kommentarId), kommentarCommand), + KommentarRemoteService.ITEM_NAME); + return buildResponseLink(command); } - private ResponseEntity<Void> buildResponseLink(KommentarCommand createdKommentarCommand) { + private ResponseEntity<Void> buildResponseLink(Command createdKommentarCommand) { return ResponseEntity.created(linkTo(CommandController.class).slash(createdKommentarCommand.getId()).toUri()).build(); } + CreateCommand buildCommand(Kommentar kommentar, KommentarCommand command) { + var commandBuilder = CreateCommand.builder() + .order(CommandOrder.UPDATE_ATTACHED_ITEM) + .relationId(NOT_SET) + .vorgangId(kommentar.getVorgangId()); + + return commandBuilder.body(updateKommandByCommand(kommentar, command)).build(); + } + + private Kommentar updateKommandByCommand(Kommentar kommentar, KommentarCommand command) { + return kommentar.toBuilder().text(command.getKommentar().getText()).build(); + } + @RestController @RequestMapping(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG) public static class KommentarCommandByVorgangController { @@ -37,13 +63,33 @@ public class KommentarCommandController { static final String KOMMENTAR_COMMANDS_BY_VORGANG = "/api/vorgangs/{vorgangId}/kommentarCommands"; @Autowired - private KommentarService service; + private CommandByRelationController commandByRelationController; + + @Autowired + private CurrentUserService userService; @PostMapping() public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand command, @PathVariable String vorgangId) { - var created = service.createCommand(vorgangId, command); + var createdCommand = commandByRelationController.createCommand(buildCommand(vorgangId, command), KommentarRemoteService.ITEM_NAME); + + return ResponseEntity.created(linkTo(CommandController.class).slash(createdCommand.getId()).toUri()).build(); + } - return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build(); + CreateCommand buildCommand(String vorgangId, KommentarCommand command) { + return CreateCommand.builder() + .vorgangId(vorgangId) + .order(CommandOrder.CREATE_ATTACHED_ITEM) + .relationId(NOT_SET) + .body(buildBody(command.getKommentar())) + .build(); } + + Kommentar buildBody(Kommentar kommentar) { + return kommentar.toBuilder() + .createdAt(ZonedDateTime.now().withNano(0)) + .createdBy(userService.getUserId().toString()) + .build(); + } + } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java index 23263f80c3f20a7b8314a5658843a8ad0e25e58e..c36561d38afa4080e10c69b1782aa37e57095400 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java @@ -1,5 +1,8 @@ package de.itvsh.goofy.kommentar; +import java.time.ZonedDateTime; +import java.util.Map; + import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; @@ -7,21 +10,27 @@ import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.ReportingPolicy; import org.mapstruct.ValueMapping; -import de.itvsh.goofy.common.IgnoreGrpcFields; import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; -import de.itvsh.ozg.pluto.kommentar.GrpcKommentar; @Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) public interface KommentarMapper { - @Mapping(target = "textBytes", ignore = true) - @IgnoreGrpcFields - GrpcKommentar toGrpcKommentar(Kommentar kommentar); - - Kommentar toKommentar(GrpcKommentar grpcKommentar); + static final String ID = "id"; + static final String TEXT = "text"; + static final String CREATED_BY = "createdBy"; + static final String CREATED_AT = "createdAt"; @Mapping(target = "kommentar", ignore = true) @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) @ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL) KommentarCommand toKommentarCommand(GrpcCommand command); + + default Kommentar fromItemMap(Map<String, Object> map) { + return Kommentar.builder() + .id((String) map.get(ID)) + .createdAt(ZonedDateTime.parse((String) map.get(CREATED_AT))) + .createdBy((String) map.get(CREATED_BY)) + .text((String) map.get(TEXT)) + .build(); + } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java index ae337b684cfd9d475ace5e633f217364c2514092..11ee02a8f99dc649ec533afcafbb1a75a32c4299 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java @@ -5,60 +5,48 @@ import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.goofy.common.callcontext.ContextService; -import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; -import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; -import de.itvsh.ozg.pluto.kommentar.GrpcFindKommentarsByVorgangIdRequest; -import de.itvsh.ozg.pluto.kommentar.GrpcFindKommentarsByVorgangIdResponse; -import de.itvsh.ozg.pluto.kommentar.GrpcGetKommentarRequest; -import de.itvsh.ozg.pluto.kommentar.GrpcGetKommentarResponse; -import de.itvsh.ozg.pluto.kommentar.KommentarServiceGrpc.KommentarServiceBlockingStub; +import de.itvsh.goofy.GoofyServerApplication; +import de.itvsh.ozg.pluto.common.GrpcObjectMapper; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.itvsh.ozg.pluto.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; @Service class KommentarRemoteService { + static final String ITEM_NAME = "Kommentar"; - @GrpcClient("pluto") - private KommentarServiceBlockingStub serviceStub; - @Autowired - private ContextService contextService; + @GrpcClient(GoofyServerApplication.GRPC_CLIENT) + private VorgangAttachedItemServiceBlockingStub vorgangAttachedItemServiceStub; @Autowired private KommentarMapper mapper; + @Autowired + private GrpcObjectMapper grpcObjectMapper; public Stream<Kommentar> findByVorgangId(String vorgangId) { - GrpcFindKommentarsByVorgangIdResponse response = serviceStub - .findKommentarsByVorgangId(buildFindKommentarsByVorgangRequest(vorgangId)); + GrpcFindVorgangAttachedItemResponse response = vorgangAttachedItemServiceStub + .find(buildFindRequest(vorgangId)); - return response.getKommentarsList().stream().map(mapper::toKommentar); + return response.getVorgangAttachedItemsList().stream() + .map(item -> grpcObjectMapper.mapFromGrpc(item.getItem())) + .map(mapper::fromItemMap); } - private GrpcFindKommentarsByVorgangIdRequest buildFindKommentarsByVorgangRequest(String vorgangId) { - return GrpcFindKommentarsByVorgangIdRequest.newBuilder().setVorgangId(vorgangId).build(); + GrpcFindVorgangAttachedItemRequest buildFindRequest(String vorgangId) { + return GrpcFindVorgangAttachedItemRequest.newBuilder() + .setVorgangId(vorgangId) + .setItemName(ITEM_NAME) + .build(); } public Kommentar getById(String kommentarId) { - GrpcGetKommentarResponse response = serviceStub.getKommentar(buildGetKommentarRequest(kommentarId)); - - return mapper.toKommentar(response.getKommentar()); - } - - private GrpcGetKommentarRequest buildGetKommentarRequest(String kommentarId) { - return GrpcGetKommentarRequest.newBuilder().setId(kommentarId).build(); + var response = vorgangAttachedItemServiceStub.getById(buildRequest(kommentarId)); + var kommentar = mapper.fromItemMap(grpcObjectMapper.mapFromGrpc(response.getVorgangAttachedItem().getItem())); + return kommentar.toBuilder().vorgangId(response.getVorgangAttachedItem().getVorgangId()).build(); } - public KommentarCommand sendKommentarCommand(String relationId, KommentarCommand command) { - var request = buildCreateCommandRequest(relationId, command); - var response = serviceStub.createCommand(request); - - return mapper.toKommentarCommand(response.getCommand()); - } - - GrpcCreateCommandRequest buildCreateCommandRequest(String relationId, KommentarCommand command) { - return GrpcCreateCommandRequest.newBuilder() - .setCallContext(contextService.createCallContext()) - .setRelationId(relationId) - .setOrder(GrpcOrder.valueOf(command.getOrder().name())) - .setKommentar(mapper.toGrpcKommentar(command.getKommentar())) - .build(); + private GrpcVorgangAttachedItemRequest buildRequest(String kommentarId) { + return GrpcVorgangAttachedItemRequest.newBuilder().setId(kommentarId).build(); } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java index 84b0c3fa3d435b273887d916c533f5e6f774e031..8b14e5f2262ef7a7628d9c2526f3704fa9654707 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java @@ -2,8 +2,6 @@ package de.itvsh.goofy.kommentar; import java.util.stream.Stream; -import javax.validation.Valid; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -22,8 +20,4 @@ class KommentarService { public Kommentar getById(String kommentarId) { return remoteService.getById(kommentarId); } - - public KommentarCommand createCommand(String relationId, @Valid KommentarCommand command) { - return remoteService.sendKommentarCommand(relationId, command); - } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/GrpcKommentarTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/GrpcKommentarTestFactory.java deleted file mode 100644 index 6064c182ae49773e18bd7a6b57a612bfca5e9041..0000000000000000000000000000000000000000 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/GrpcKommentarTestFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.itvsh.goofy.kommentar; - -import de.itvsh.ozg.pluto.kommentar.GrpcKommentar; - -public class GrpcKommentarTestFactory { - - final static String ID = KommentarTestFactory.ID; - final static String CREATED_BY = KommentarTestFactory.CREATED_BY; - final static String CREATED_BY_NAME = KommentarTestFactory.CREATED_BY_NAME; - final static String CREATED_AT_STR = KommentarTestFactory.CREATED_AT_STR; - final static String TEXT = KommentarTestFactory.TEXT; - - public static GrpcKommentar create() { - return createBuilder().build(); - } - - public static GrpcKommentar.Builder createBuilder() { - return GrpcKommentar.newBuilder() - .setId(ID) - .setCreatedBy(CREATED_BY) - .setCreatedByName(CREATED_BY_NAME) - .setCreatedAt(CREATED_AT_STR) - .setText(TEXT); - } -} diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java index 2f67bba4bd69e06282af0f8d3519439c3c6616d1..3eb84c3ec6ae60f487ba067875086369004b81bc 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java @@ -7,6 +7,8 @@ import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import java.util.UUID; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -19,14 +21,19 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.command.CommandOrder; +import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.goofy.common.command.CreateCommand; +import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.kommentar.KommentarCommandController.KommentarCommandByVorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class KommentarCommandControllerTest { @Captor - private ArgumentCaptor<KommentarCommand> commandCaptor; + private ArgumentCaptor<CreateCommand> commandCaptor; @Nested class TestCreateKommentarCommandByVorgang { @@ -35,13 +42,18 @@ class KommentarCommandControllerTest { private KommentarCommandByVorgangController controller; @Mock private KommentarService service; + @Mock + private CommandByRelationController commandByRelationController; + @Mock + private CurrentUserService userService; private MockMvc mockMvc; @BeforeEach void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - when(service.createCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create()); + when(userService.getUserId()).thenReturn(UserId.from(UUID.randomUUID())); + when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); } @Test @@ -53,19 +65,21 @@ class KommentarCommandControllerTest { void shouldCallService() throws Exception { doRequest(); - verify(service).createCommand(eq(VorgangHeaderTestFactory.ID), notNull()); + verify(commandByRelationController).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); } @Test void shouldGiveCommandToService() throws Exception { doRequest(); - verify(service).createCommand(eq(VorgangHeaderTestFactory.ID), commandCaptor.capture()); + verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString()); var command = commandCaptor.getValue(); assertThat(command).usingRecursiveComparison() - .ignoringFields("kommentar.id", "kommentar.createdBy", "kommentar.createdByName", "kommentar.createdAt") - .isEqualTo(KommentarCommandTestFactory.createBuilder().id(null).build()); + .ignoringFields("body", "status") + .isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.CREATE_ATTACHED_ITEM) + .relationId(KommentarCommandController.NOT_SET) + .id(null).build()); } private ResultActions doRequest() throws Exception { @@ -83,6 +97,8 @@ class KommentarCommandControllerTest { @InjectMocks private KommentarCommandController controller; @Mock + private CommandByRelationController commandByRelationController; + @Mock private KommentarService service; private MockMvc mockMvc; @@ -90,8 +106,8 @@ class KommentarCommandControllerTest { @BeforeEach void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - when(service.createCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.createBuilder() - .order(CommandOrder.EDIT_KOMMENTAR).build()); + when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); + when(service.getById(any())).thenReturn(KommentarTestFactory.createBuilder().vorgangId(VorgangHeaderTestFactory.ID).build()); } @Test @@ -103,19 +119,21 @@ class KommentarCommandControllerTest { void shouldCallService() throws Exception { doRequest(); - verify(service).createCommand(anyString(), notNull()); + verify(service).getById(any()); } @Test void shouldGiveCommandToService() throws Exception { doRequest(); - verify(service).createCommand(anyString(), commandCaptor.capture()); + verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString()); var command = commandCaptor.getValue(); assertThat(command).usingRecursiveComparison() - .ignoringFields("kommentar.id", "kommentar.createdBy", "kommentar.createdByName", "kommentar.createdAt") - .isEqualTo(KommentarCommandTestFactory.createBuilder().id(null).build()); + .ignoringFields("body", "status") + .isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.UPDATE_ATTACHED_ITEM) + .relationId(KommentarCommandController.NOT_SET).id(null) + .build()); } @Test diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java index 000d82d4797926a848d0445e598241f7148f7d74..37c96c2c937358f455fab7fcc967503267cf42ab 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java @@ -22,6 +22,8 @@ import org.springframework.test.web.servlet.ResultActions; import de.itvsh.goofy.common.ValidationMessageCodes; import de.itvsh.goofy.common.command.CommandOrder; +import de.itvsh.goofy.common.command.CommandRemoteService; +import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.kommentar.KommentarCommandController.KommentarCommandByVorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -34,6 +36,8 @@ class KommentarCommandITCase { private MockMvc mockMvc; @MockBean private KommentarRemoteService remoteService; + @MockBean + private CommandRemoteService commandRemoteService; @WithMockUser @Nested @@ -41,14 +45,15 @@ class KommentarCommandITCase { @BeforeEach void initTest() { - when(remoteService.sendKommentarCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create()); + when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create()); + when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); } @Test void shouldCreateCommand() throws Exception { doRequestByKommentarId(createValidRequestContent()).andExpect(status().isCreated()); - verify(remoteService).sendKommentarCommand(eq(KommentarTestFactory.ID), any()); + verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); } @WithMockUser @@ -63,7 +68,7 @@ class KommentarCommandITCase { doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text")) + .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -73,7 +78,7 @@ class KommentarCommandITCase { String content = buildContentWithText(StringUtils.EMPTY); doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text")); + .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")); } @@ -88,7 +93,7 @@ class KommentarCommandITCase { private String buildContentWithText(String text) { return createRequestContent(KommentarCommandTestFactory.createBuilder() - .order(CommandOrder.EDIT_KOMMENTAR) + .order(CommandOrder.CREATE_ATTACHED_ITEM) .kommentar(KommentarTestFactory.createBuilder().text(text).build()) .build()); } @@ -107,14 +112,15 @@ class KommentarCommandITCase { @BeforeEach void initTest() { - when(remoteService.sendKommentarCommand(anyString(), any())).thenReturn(KommentarCommandTestFactory.create()); + when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create()); + when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); } @Test void shouldCreateCommand() throws Exception { doRequestByVorgangId(createValidRequestContent()).andExpect(status().isCreated()); - verify(remoteService).sendKommentarCommand(eq(VorgangHeaderTestFactory.ID), any()); + verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); } @WithMockUser @@ -129,7 +135,7 @@ class KommentarCommandITCase { doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text")) + .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -139,7 +145,7 @@ class KommentarCommandITCase { String content = buildContentWithText(StringUtils.EMPTY); doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.kommentar.text")); + .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")); } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java index 379f512ecf1106daa56f4fcdc075dfa559db6642..74380e47bbbb5e6315f72c9cac7853d6aaf961a2 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java @@ -11,39 +11,37 @@ class KommentarMapperTest { private KommentarMapper mapper = Mappers.getMapper(KommentarMapper.class); @Nested - class TestFromGrpc { - + class TestFromItemMap { @Test - void shouldMap() { - var kommentar = mapper.toKommentar(GrpcKommentarTestFactory.create()); + void shouldMapId() { + var kommentar = map(); - assertThat(kommentar).isNotNull().usingRecursiveComparison().isEqualTo(KommentarTestFactory.create()); + assertThat(kommentar.getId()).isEqualTo(KommentarTestFactory.ID); } @Test - void shouldHandleNull() { - var grpcKommentar = mapper.toKommentar(null); + void shouldMapCreatedBy() { + var kommentar = map(); - assertThat(grpcKommentar).isNull(); + assertThat(kommentar.getCreatedBy()).isEqualTo(KommentarTestFactory.CREATED_BY); } - } - - @Nested - class TestToGrpc { @Test - void shouldMap() { - var grpcKommentar = mapper.toGrpcKommentar(KommentarTestFactory.createBuilder().id(null).build()); + void shouldMapCreatedAt() { + var kommentar = map(); - assertThat(grpcKommentar).isNotNull().usingRecursiveComparison().ignoringFields("id_", "memoizedHashCode") - .isEqualTo(GrpcKommentarTestFactory.create()); + assertThat(kommentar.getCreatedAt()).isEqualTo(KommentarTestFactory.CREATED_AT); } @Test - void shouldHandleNull() { - var grpcKommentar = mapper.toGrpcKommentar(null); + void shouldMapText() { + var kommentar = map(); - assertThat(grpcKommentar).isNull(); + assertThat(kommentar.getText()).isEqualTo(KommentarTestFactory.TEXT); } } + + private Kommentar map() { + return mapper.fromItemMap(KommentarTestFactory.createAsMap()); + } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java index 4e30b113e9e504fd110bda0daf2a9cdca21a1440..45ad4afbbbfec175aceb96ebc97e9c367875affa 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java @@ -3,28 +3,24 @@ package de.itvsh.goofy.kommentar; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.itvsh.goofy.common.callcontext.ContextService; -import de.itvsh.goofy.common.command.GrpcCommandResponseTestFactory; +import de.itvsh.goofy.vorgang.GrpcVorgangAttachedItemTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; -import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; -import de.itvsh.ozg.pluto.grpc.command.GrpcCommandResponse; -import de.itvsh.ozg.pluto.kommentar.GrpcFindKommentarsByVorgangIdRequest; -import de.itvsh.ozg.pluto.kommentar.GrpcFindKommentarsByVorgangIdResponse; -import de.itvsh.ozg.pluto.kommentar.GrpcGetKommentarRequest; -import de.itvsh.ozg.pluto.kommentar.GrpcGetKommentarResponse; -import de.itvsh.ozg.pluto.kommentar.GrpcKommentar; -import de.itvsh.ozg.pluto.kommentar.KommentarServiceGrpc.KommentarServiceBlockingStub; +import de.itvsh.ozg.pluto.common.GrpcObjectMapper; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemResponse; +import de.itvsh.ozg.pluto.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceBlockingStub; class KommentarRemoteServiceTest { @@ -33,33 +29,34 @@ class KommentarRemoteServiceTest { private KommentarRemoteService service; @Mock - private KommentarMapper mapper; + private VorgangAttachedItemServiceBlockingStub vorgangAttachedItemServiceStub; @Mock - private KommentarServiceBlockingStub serviceStub; + private KommentarMapper mapper; @Mock - private ContextService contextService; + private GrpcObjectMapper grpcObjectMapper; - private GrpcKommentar kommentar = GrpcKommentarTestFactory.create(); + private GrpcVorgangAttachedItem kommentar = GrpcVorgangAttachedItemTestFactory.create(); @Nested class TestFindByVorgangId { - private GrpcFindKommentarsByVorgangIdRequest request = GrpcFindKommentarsByVorgangIdRequest.newBuilder() - .setVorgangId(VorgangHeaderTestFactory.ID).build(); - private GrpcFindKommentarsByVorgangIdResponse response = GrpcFindKommentarsByVorgangIdResponse.newBuilder() - .addKommentars(kommentar) - .addKommentars(kommentar).build(); + private GrpcFindVorgangAttachedItemRequest request = GrpcFindVorgangAttachedItemRequest.newBuilder() + .setVorgangId(VorgangHeaderTestFactory.ID).setItemName(KommentarRemoteService.ITEM_NAME).build(); + private GrpcFindVorgangAttachedItemResponse response = GrpcFindVorgangAttachedItemResponse.newBuilder() + .clearVorgangAttachedItems() + .addVorgangAttachedItems(kommentar) + .addVorgangAttachedItems(kommentar).build(); @BeforeEach void mockStub() { - when(serviceStub.findKommentarsByVorgangId(any())).thenReturn(response); + when(vorgangAttachedItemServiceStub.find(any())).thenReturn(response); } @Test void shouldCallStub() { service.findByVorgangId(VorgangHeaderTestFactory.ID); - verify(serviceStub).findKommentarsByVorgangId(request); + verify(vorgangAttachedItemServiceStub).find(request); } @Test @@ -67,78 +64,39 @@ class KommentarRemoteServiceTest { Stream<Kommentar> result = service.findByVorgangId(VorgangHeaderTestFactory.ID); collectStreamElementsToTriggerLazyStream(result); - verify(mapper, times(2)).toKommentar(kommentar); + verify(mapper, times(2)).fromItemMap(any()); } private void collectStreamElementsToTriggerLazyStream(Stream<Kommentar> stream) { - stream.collect(Collectors.toList()); + stream.toList(); } } @Nested class TestGetById { - - private GrpcGetKommentarRequest request = GrpcGetKommentarRequest.newBuilder().setId(KommentarTestFactory.ID).build(); - private GrpcGetKommentarResponse response = GrpcGetKommentarResponse.newBuilder().setKommentar(kommentar).build(); + GrpcVorgangAttachedItemResponse response = GrpcVorgangAttachedItemResponse.newBuilder() + .setVorgangAttachedItem(GrpcVorgangAttachedItemTestFactory.create()).build(); + GrpcVorgangAttachedItemRequest request = GrpcVorgangAttachedItemRequest.newBuilder().setId(KommentarTestFactory.ID).build(); @BeforeEach void mockStub() { - when(serviceStub.getKommentar(any())).thenReturn(response); + when(vorgangAttachedItemServiceStub.getById(any())).thenReturn(response); + when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(KommentarTestFactory.createAsMap()); + when(mapper.fromItemMap(any())).thenReturn(KommentarTestFactory.create()); } @Test void shouldCallStub() { service.getById(KommentarTestFactory.ID); - verify(serviceStub).getKommentar(request); + verify(vorgangAttachedItemServiceStub).getById(request); } @Test void shouldCallMapper() { service.getById(KommentarTestFactory.ID); - verify(mapper).toKommentar(kommentar); - } - } - - @Nested - class TestSendKommentarCommand { - - private GrpcCallContext callContext = GrpcCallContext.newBuilder().build(); - private GrpcCommandResponse response = GrpcCommandResponseTestFactory.createBuilder().build(); - - @BeforeEach - void initTest() { - when(serviceStub.createCommand(any())).thenReturn(response); - when(contextService.createCallContext()).thenReturn(callContext); - when(mapper.toGrpcKommentar(any())).thenReturn(GrpcKommentarTestFactory.create()); - when(mapper.toKommentarCommand(any())).thenReturn(KommentarCommandTestFactory.create()); - } - - @Test - @DisplayName("Should call buildCreateCommandRequest with VorgangId") - void shouldCallCreateRequestWithVorgangId() { - doRequest(); - - verify(service).buildCreateCommandRequest(eq(VorgangHeaderTestFactory.ID), any()); - } - - @Test - void shouldCallStub() { - doRequest(); - - verify(serviceStub).createCommand(any()); - } - - @Test - void shouldMapResult() { - doRequest(); - - verify(mapper).toKommentarCommand(any()); - } - - private void doRequest() { - service.sendKommentarCommand(VorgangHeaderTestFactory.ID, KommentarCommandTestFactory.create()); + verify(mapper).fromItemMap(any()); } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java index 7d9853445c31029cbb39aace9a9e75a4bfb5937b..d7193d38b9d8ba7ae8385d7e2414f0e42a2d45e8 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java @@ -1,7 +1,5 @@ package de.itvsh.goofy.kommentar; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import org.junit.jupiter.api.Nested; @@ -40,27 +38,4 @@ class KommentarServiceTest { verify(remoteService).findByVorgangId(VorgangHeaderTestFactory.ID); } } - - @Nested - class TestCreateCommand { - - @Test - void shouldCallRemoteService() { - KommentarCommand command = KommentarCommandTestFactory.create(); - - service.createCommand(VorgangHeaderTestFactory.ID, command); - - verify(remoteService).sendKommentarCommand(VorgangHeaderTestFactory.ID, command); - } - - @Test - void shouldReturnCorrectResult() { - KommentarCommand resultFromRemoteService = KommentarCommandTestFactory.create(); - when(remoteService.sendKommentarCommand(anyString(), any())).thenReturn(resultFromRemoteService); - - KommentarCommand resultFromService = service.createCommand(VorgangHeaderTestFactory.ID, KommentarCommandTestFactory.create()); - - assertThat(resultFromService).isSameAs(resultFromRemoteService); - } - } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java index 2d7b464ec849994bd06cb7b89214ff491b7dd3bf..99abb0b24b22ca5ab6743ae4de507409dfdf0995 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java @@ -1,6 +1,7 @@ package de.itvsh.goofy.kommentar; import java.time.ZonedDateTime; +import java.util.Map; import java.util.UUID; import com.thedeanda.lorem.Lorem; @@ -15,7 +16,6 @@ public class KommentarTestFactory { public static final String ID = UUID.randomUUID().toString(); public static final String CREATED_BY = UserProfileTestFactory.ID.toString(); - public static final String CREATED_BY_NAME = lorem.getName(); public static final String CREATED_AT_STR = "2021-01-10T10:30:00Z"; public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); @@ -30,7 +30,14 @@ public class KommentarTestFactory { .id(ID) .text(TEXT) .createdBy(CREATED_BY) - .createdByName(CREATED_BY_NAME) .createdAt(CREATED_AT); } + + public static Map<String, Object> createAsMap() { + return Map.of( + KommentarMapper.ID, ID, + KommentarMapper.TEXT, TEXT, + KommentarMapper.CREATED_BY, CREATED_BY, + KommentarMapper.CREATED_AT, CREATED_AT_STR); + } }