Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement ocx-content + ocx-content-container and re-enable Storybook #52

Merged
merged 15 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
framework: {
name: '@storybook/angular',
options: {},
},
addons: [],
docs: {
autodocs: true,
},
}

15 changes: 15 additions & 0 deletions .storybook/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../tsconfig.base.json",
"exclude": [
"../**/*.spec.js",
"../**/*.test.js",
"../**/*.spec.ts",
"../**/*.test.ts",
"../**/*.spec.tsx",
"../**/*.test.tsx",
"../**/*.spec.jsx",
"../**/*.test.jsx"
],
"include": ["../**/*"]
}

2 changes: 1 addition & 1 deletion libs/portal-integration-angular/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onecx/portal-integration-angular",
"version": "3.6.0",
"version": "3.7.1",
bastianjakobi marked this conversation as resolved.
Show resolved Hide resolved
"peerDependencies": {
"@angular-architects/module-federation": "15.0.0",
"@angular/common": "^15.2.7",
Expand Down
45 changes: 44 additions & 1 deletion libs/portal-integration-angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,49 @@
"options": {
"libName": "portal-integration-angular"
}
},
"storybook": {
"executor": "@storybook/angular:start-storybook",
"options": {
"port": 4400,
"configDir": "libs/portal-integration-angular/.storybook",
"browserTarget": "portal-integration-angular:build-storybook",
"compodoc": false,
"styles": [
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"libs/portal-integration-angular/assets/styles.scss",
"libs/portal-integration-angular/.storybook/storybook.css"
]

},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"executor": "@storybook/angular:build-storybook",
"outputs": ["{options.outputDir}"],
"options": {
"outputDir": "dist/storybook/portal-integration-angular",
"configDir": "libs/portal-integration-angular/.storybook",
"browserTarget": "portal-integration-angular:build-storybook",
"compodoc": false,
"styles": [
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"libs/portal-integration-angular/assets/styles.scss",
"libs/portal-integration-angular/.storybook/storybook.css"
]

},
"configurations": {
"ci": {
"quiet": true
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { HttpClientModule } from '@angular/common/http'
import { ConfigurationService } from '../../../services/configuration.service'

function initFactory(configurationService: ConfigurationService) {
configurationService.setPortal({ baseUrl: '/demo', portalName: 'Demo', id: 'Demo', microfrontends: [] })
configurationService.setPortal({ baseUrl: '/demo', portalName: 'Demo', id: 'Demo', microfrontendRegistrations: [] })
return () => {
configurationService
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div ocxContentContainer [layout]="layout">
<ng-content></ng-content>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { OcxContentContainerComponent } from './ocx-content-container.component'
import { OcxContentContainerDirective } from '../../directives/ocx-content-container.directive'
import { Component } from '@angular/core'

// Mock host component that's used in all tests that require a dynamic layout change
// Using this mock host allows us to simulate Angular @Input mechanisms
@Component({
template: `
<ocx-content-container [layout]="layout"></ocx-content-container>
`,
})
class TestHostComponent {
layout: 'horizontal' | 'vertical' = 'horizontal';
}

describe('OcxContentContainerComponent', () => {
let component: TestHostComponent | OcxContentContainerComponent
let fixture: ComponentFixture<TestHostComponent | OcxContentContainerComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [OcxContentContainerComponent, OcxContentContainerDirective, TestHostComponent],
}).compileComponents()

fixture = TestBed.createComponent(OcxContentContainerComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})

it('should render a horizontal layout container with all expected css classes', () => {
// Check that layout is horizontal by default
expect(component.layout).toEqual('horizontal')
fixture.detectChanges()

// Check that the classList of the rendered element contains all expected classes
const expectedClasses = ['flex', 'p-3', 'gap-3', 'flex-column', 'sm:flex-row']
expect(Object.keys(fixture.debugElement.children[0].classes)).toEqual(expectedClasses)
bastianjakobi marked this conversation as resolved.
Show resolved Hide resolved
})

it('should render a vertical layout container with all expected css classes', () => {
// Replace default component with custom host component to simulate input behavior
fixture = TestBed.createComponent(TestHostComponent)
component = fixture.componentInstance
fixture.detectChanges()

// Check that layout is horizontal by default
expect(component.layout).toEqual('horizontal')

// Set layout to 'vertical'
component.layout = 'vertical'
fixture.detectChanges()

// Check that layout is now vertical
expect(component.layout).toEqual('vertical')

// Check that the classList of the rendered element contains all expected classes
const expectedClasses = ["flex", "p-3", "gap-3", "flex-column"]
expect(Object.keys(fixture.debugElement.children[0].children[0].classes)).toEqual(expectedClasses)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { OcxContentContainerDirective } from '../../directives/ocx-content-container.directive'
import { OcxContentDirective } from '../../directives/ocx-content.directive'
import { OcxContentComponent } from '../ocx-content/ocx-content.component'
import { OcxContentContainerComponent } from './ocx-content-container.component'
import { moduleMetadata, Meta } from '@storybook/angular'

export default {
title: 'OcxContentContainerComponent',
component: OcxContentContainerComponent,
argTypes: {
layout: {
options: ['horizontal', 'vertical'],
control: { type: 'select' },
},
},
decorators: [
moduleMetadata({
declarations: [OcxContentContainerDirective, OcxContentComponent, OcxContentDirective],
}),
],
} as Meta<OcxContentContainerComponent>

export const Basic = {
render: (args: OcxContentContainerComponent) => ({
props: {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<p>Content 1 nested in ocx-content-container</p>
<p>Content 2 nested in ocx-content-container</p>
</ocx-content-container>
`,
}),
args: {
layout: 'horizontal',
},
}

export const WithNestedOCXContent = {
render: (args: OcxContentContainerComponent) => ({
props: {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<ocx-content class="w-full sm:w-8">
<p>Content inside of ocx-content without title</p>
</ocx-content>
<ocx-content title="My Title" class="w-full sm:w-4">
<p>Content inside of ocx-content with title</p>
</ocx-content>
</ocx-content-container>
`,
}),
args: {
layout: 'horizontal',
},
}

export const WithNestedOCXContentContainer = {
render: (args: OcxContentContainerComponent) => ({
props: {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<ocx-content-container>
<p>Horizontal content in nested ocx-content-container 1</p>
<p>Horizontal content in nested ocx-content-container 1</p>
</ocx-content-container>
<ocx-content-container layout="vertical">
<p>Vertical content in nested ocx-content-container 1</p>
<p>Vertical content in nested ocx-content-container 1</p>
</ocx-content-container>
</ocx-content-container>
`,
}),
args: {
layout: 'horizontal',
},
}

export const DirectiveOnly = {
render: (args: OcxContentContainerComponent) => ({
props: {
...args,
},
template: `
<div ocxContentContainer layout="${args.layout}">
<p>Content 1 nested inside of a div with the ocxContentContainer directive applied to it.</p>
<p>Content 2 nested inside of a div with the ocxContentContainer directive applied to it.</p>
</div>
`,
}),
args: {
layout: 'horizontal',
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, Input } from '@angular/core'

@Component({
selector: 'ocx-content-container',
templateUrl: './ocx-content-container.component.html',
})
export class OcxContentContainerComponent {
/**
* Allows specifying the layout direction of the container
*/
@Input() layout: 'vertical' | 'horizontal' = 'horizontal';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div [ocxContent]="title">
<ng-content></ng-content>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { OcxContentComponent } from './ocx-content.component'
import { Component } from '@angular/core'
import { OcxContentDirective } from '../../directives/ocx-content.directive'
import { By } from '@angular/platform-browser'

// Mock host component that's used in all tests that require a dynamic ocxContent title change
// Using this mock host allows us to simulate Angular @Input mechanisms
@Component({
template: ` <ocx-content [title]="title"></ocx-content> `,
})
class TestHostComponent {
title = ''
}

describe('OcxContentComponent', () => {
let component: TestHostComponent | OcxContentComponent
let fixture: ComponentFixture<TestHostComponent | OcxContentComponent>
const titleElemID = 'ocxContentTitleElement'
const testComponentTitle = 'My cool title'

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [OcxContentComponent, OcxContentDirective, TestHostComponent],
}).compileComponents()

fixture = TestBed.createComponent(OcxContentComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})

it('should render a ocxContent card with no title by default', () => {
// Check that the title is falsy (in this case '') by default
expect(component.title).toBeFalsy()
fixture.detectChanges()

// Check that classList of element contains all expected classes
const expectedClasses = ['card']
expect(Object.keys(fixture.debugElement.children[0].classes)).toEqual(expectedClasses)

// Check that title element doesn't exist inside of ocxContent card
expect(fixture.debugElement.query(By.css(`#${titleElemID}`))).toBeFalsy()
bastianjakobi marked this conversation as resolved.
Show resolved Hide resolved
})

it('should render a ocxContent card with a title, when given a title via input', () => {
// Replace default component with custom host component to simulate input behavior
fixture = TestBed.createComponent(TestHostComponent)
component = fixture.componentInstance
fixture.detectChanges()

// Check that initial rendering without title still works as expected
// Check that the title is falsy (in this case '') by default
expect(component.title).toBeFalsy()
fixture.detectChanges()

// Check that classList of element contains all expected classes
const expectedClasses = ['card']
expect(Object.keys(fixture.debugElement.children[0].children[0].classes)).toEqual(expectedClasses)

// Check that title element doesn't exist inside of ocxContent card
expect(fixture.debugElement.query(By.css(`#${titleElemID}`))).toBeFalsy()

// Set title to a specific value
component.title = testComponentTitle
fixture.detectChanges()

// Check that title now matches the expected value
expect(component.title).toEqual(testComponentTitle)

// Check that title element has been rendered and contains the expected text content
const titleElement = fixture.debugElement.query(By.css(`#${titleElemID}`))
expect(titleElement).toBeTruthy()
expect(titleElement.nativeElement.textContent).toEqual(testComponentTitle)
})
})
Loading
Loading