Skip to content

Commit

Permalink
Merge pull request #615 from Financial-Times/CPP-465-improve-x-intera…
Browse files Browse the repository at this point in the history
…ction-test-coverage

CPP-465 Added tests for serialiser.js
  • Loading branch information
serena97 authored Sep 22, 2021
2 parents 5d8a903 + bab58c1 commit 7a46bb8
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
70 changes: 70 additions & 0 deletions components/x-interaction/__tests__/serialiser.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Serialiser } from '../src/concerns/serialiser'
import * as registerComponent from '../src/concerns/register-component'
const { withActions } = require('../')
const xEngine = require('@financial-times/x-engine')

describe('serialiser', () => {
let serialiser
let Component
let name
beforeAll(() => {
serialiser = new Serialiser()
name = 'testComponent'
Component = withActions({})(() => null)
})

it('pushes Component to data array in addData', () => {
jest.spyOn(registerComponent, 'getComponent').mockReturnValue(Component)
jest.spyOn(registerComponent, 'getComponentName').mockReturnValue(name)

serialiser.addData('id', Component, {})

expect(serialiser.data.length).toEqual(1)
})

it('throws Error if component is not registered in addData', () => {
jest.spyOn(registerComponent, 'getComponent').mockReturnValue(undefined)

expect(() => serialiser.addData('id', Component, {})).toThrow(
`a Serialiser's addData was called for an unregistered component. ensure you're registering your component before attempting to output the hydration data`
)
})

it('throws Error if serialiser is destroyed in addData', () => {
serialiser.destroyed = true
jest.spyOn(registerComponent, 'getComponent').mockReturnValue(Component)

expect(() => serialiser.addData('id', Component, {})).toThrow(
`an interaction component was rendered after flushHydrationData was called. ensure you're outputting the hydration data after rendering every component`
)
})

it('throws Error if serialiser is destroyed in flushHydrationData', () => {
serialiser.destroyed = true
expect(() => serialiser.flushHydrationData()).toThrow(
`a Serialiser's flushHydrationData was called twice. ensure you're not reusing a Serialiser between requests`
)
})

it('returns data and sets destroyed to true if serialiser is not destroyed in flushHydrationData', () => {
serialiser.destroyed = false
serialiser.data = [{ id: 'id', component: Component, props: '' }]

const data = serialiser.flushHydrationData()

expect(data).toEqual(serialiser.data)
expect(serialiser.destroyed).toEqual(true)
})

it('renders the hydration data in outputHydrationData', () => {
const expectedData = {}
jest.spyOn(xEngine, 'h').mockReturnValue('target')
jest.spyOn(xEngine, 'render').mockReturnValue(expectedData)

const data = serialiser.outputHydrationData()

expect(xEngine.render).toHaveBeenCalled()
expect(xEngine.h).toHaveBeenCalled()
expect(data).toEqual(expectedData)
})
})
3 changes: 3 additions & 0 deletions components/x-interaction/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ export const Greeting = greetingActions(BaseGreeting);

### Hydrating server-rendered markup

[Hydration](https://en.wikipedia.org/wiki/Hydration_(web_development)#:~:text=In%20web%20development%2C%20hydration%20or,handlers%20to%20the%20HTML%20elements.
): a technique in which client-side JavaScript converts a static HTML web page done by server-side rendering, into a dynamic web page by attaching event handlers to the HTML elements.

When you have an `x-interaction` component rendered by the server, and you want to attach the client-side version of the component to handle the actions, rather than rendering the component manually (which might become unwieldy, especially if you have many components & instances on the page), you can have `x-interaction` manage it for you.

There are three parts to this: registering the component, serialising and hydrating.
Expand Down

0 comments on commit 7a46bb8

Please sign in to comment.