Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
277 changes: 47 additions & 230 deletions .pnp.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarn/versions/cf38ca6f.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
releases:
"@atls/react-identity-links": major
"@atls/react-kratos": patch
12 changes: 2 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,7 @@
},
"devDependencies": {
"@atls/raijin": "1.1.1",
"@types/node": "22.10.1",
"@types/testing-library__jest-dom": "5.14.2",
"eslint": "9.16.0",
"typescript": "5.5.4"
"@types/node": "22.10.1"
},
"packageManager": "yarn@4.18.0",
"testIgnorePatterns": [
"packages/identity-links/src/identity-link.component.test.tsx",
"packages/identity-links/src/use-identity-url.hook.test.ts"
],
"typecheckSkipLibCheck": true
"packageManager": "yarn@4.18.0"
}
12 changes: 7 additions & 5 deletions packages/identity-links/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
"name": "@atls/react-identity-links",
"version": "0.1.1",
"license": "MIT",
"type": "module",
"main": "src/index.ts",
"files": [
"dist"
"dist",
"!dist/*.test.*"
],
"scripts": {
"build": "yarn library build",
Expand All @@ -15,13 +17,13 @@
"tldjs": "^2.3.1"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/react": "16.1.0",
"@types/node": "22.10.1",
"@types/react": "18.3.6",
"@types/react-dom": "^18.2.7",
"@types/testing-library__jest-dom": "^5.14.1",
"@types/tldjs": "2.3.4",
"global-jsdom": "25.0.0",
"jsdom": "25.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
53 changes: 25 additions & 28 deletions packages/identity-links/src/identity-link.component.test.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
// /**
// * @jest-environment jsdom
// */
import 'global-jsdom/register'

// import '@testing-library/jest-dom/extend-expect'
import assert from 'node:assert/strict'
import { afterEach } from 'node:test'
import { test } from 'node:test'

// import { render } from '@testing-library/react'
// import React from 'react'
import { cleanup } from '@testing-library/react'
import { render } from '@testing-library/react'
import React from 'react'

// import { IdentityLink } from './identity-link.component'
import { IdentityLink } from './identity-link.component.js'

// describe('identity-link.component', () => {
// const originalLocation = window.location
const dom = globalThis as typeof globalThis & {
$jsdom: { reconfigure: (options: { url: string }) => void }
}

// const mockWindowLocation = (newLocation: Location | URL | string): void => {
// // @ts-expect-error location can be optional
// delete window.location
// window.location = newLocation as Location | (Location & string)
// }
dom.$jsdom.reconfigure({ url: 'https://identity.atls.tech/' })

// afterEach(() => {
// mockWindowLocation(originalLocation)
// })
afterEach(() => {
cleanup()
})

// it('without params', async () => {
// mockWindowLocation(new URL('https://identity.monstrs.dev'))
test('renders a login link with the current URL as return target', async () => {
const { findByRole } = render(
<IdentityLink returnTo>{(url) => <a href={url}>Login</a>}</IdentityLink>
)

// const { getByText } = render(
// <IdentityLink returnTo>{(url) => <a href={url}>Login</a>}</IdentityLink>
// )
const link = await findByRole('link', { name: 'Login' })

// expect(getByText('Login')).toHaveAttribute(
// 'href',
// 'https://accounts.monstrs.dev/auth/login?return_to=https://identity.monstrs.dev/'
// )
// })
// })
assert.equal(
link.getAttribute('href'),
'https://accounts.atls.tech/auth/login?return_to=https://identity.atls.tech/'
)
})
4 changes: 2 additions & 2 deletions packages/identity-links/src/identity-link.component.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { FC } from 'react'

import type { IdentityLinkProps } from './identity-url.interfaces'
import type { IdentityLinkProps } from './identity-url.interfaces.js'

import { useIdentityUrl } from './use-identity-url.hook'
import { useIdentityUrl } from './use-identity-url.hook.js'

export const IdentityLink: FC<IdentityLinkProps> = ({ children, type, returnTo }) => {
const url = useIdentityUrl({ type, returnTo })
Expand Down
6 changes: 3 additions & 3 deletions packages/identity-links/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './identity-link.component'
export type * from './identity-url.interfaces'
export * from './use-identity-url.hook'
export * from './identity-link.component.js'
export type * from './identity-url.interfaces.js'
export * from './use-identity-url.hook.js'
126 changes: 65 additions & 61 deletions packages/identity-links/src/use-identity-url.hook.test.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,65 @@
// /**
// * @jest-environment jsdom
// */

// import { renderHook } from '@testing-library/react-hooks'

// import { useIdentityUrl } from './use-identity-url.hook'

// describe('use-identity-url', () => {
// const originalLocation = window.location

// const mockWindowLocation = (newLocation: Location | URL | string): void => {
// // @ts-expect-error location can be optional
// delete window.location
// window.location = newLocation as Location | (Location & string)
// }

// afterEach(() => {
// mockWindowLocation(originalLocation)
// })

// it('without params', () => {
// mockWindowLocation(new URL('https://identity.monstrs.dev'))

// const { result } = renderHook(() => useIdentityUrl({ returnTo: true }))

// expect(result.current).toBe(
// 'https://accounts.monstrs.dev/auth/login?return_to=https://identity.monstrs.dev/'
// )
// })

// it('custom type', () => {
// mockWindowLocation(new URL('https://identity.monstrs.dev'))

// const { result } = renderHook(() => useIdentityUrl({ type: 'registration', returnTo: true }))

// expect(result.current).toBe(
// 'https://accounts.monstrs.dev/auth/registration?return_to=https://identity.monstrs.dev/'
// )
// })

// it('return to path', () => {
// mockWindowLocation(new URL('https://identity.monstrs.dev'))

// const { result } = renderHook(() => useIdentityUrl({ returnTo: { pathname: '/custom' } }))

// expect(result.current).toBe(
// 'https://accounts.monstrs.dev/auth/login?return_to=https://identity.monstrs.dev/custom'
// )
// })

// it('return to url', () => {
// mockWindowLocation(new URL('https://identity.monstrs.dev'))

// const { result } = renderHook(() => useIdentityUrl({ returnTo: { subdomain: 'custom' } }))

// expect(result.current).toBe(
// 'https://accounts.monstrs.dev/auth/login?return_to=https://custom.monstrs.dev/'
// )
// })
// })
import 'global-jsdom/register'

import assert from 'node:assert/strict'
import { afterEach } from 'node:test'
import { test } from 'node:test'

import { cleanup } from '@testing-library/react'
import { renderHook } from '@testing-library/react'
import { waitFor } from '@testing-library/react'

import { useIdentityUrl } from './use-identity-url.hook.js'

const dom = globalThis as typeof globalThis & {
$jsdom: { reconfigure: (options: { url: string }) => void }
}

dom.$jsdom.reconfigure({ url: 'https://identity.atls.tech/' })

afterEach(() => {
cleanup()
})

test('uses the current URL as the default return target', async () => {
const { result } = renderHook(() => useIdentityUrl({ returnTo: true }))

await waitFor(() => {
assert.equal(
result.current,
'https://accounts.atls.tech/auth/login?return_to=https://identity.atls.tech/'
)
})
})

test('uses the requested identity action', async () => {
const { result } = renderHook(() => useIdentityUrl({ type: 'registration', returnTo: true }))

await waitFor(() => {
assert.equal(
result.current,
'https://accounts.atls.tech/auth/registration?return_to=https://identity.atls.tech/'
)
})
})

test('uses a custom return path', async () => {
const { result } = renderHook(() => useIdentityUrl({ returnTo: { pathname: '/custom' } }))

await waitFor(() => {
assert.equal(
result.current,
'https://accounts.atls.tech/auth/login?return_to=https://identity.atls.tech/custom'
)
})
})

test('uses a custom return subdomain', async () => {
const { result } = renderHook(() => useIdentityUrl({ returnTo: { subdomain: 'custom' } }))

await waitFor(() => {
assert.equal(
result.current,
'https://accounts.atls.tech/auth/login?return_to=https://custom.atls.tech/'
)
})
})
8 changes: 4 additions & 4 deletions packages/identity-links/src/use-identity-url.hook.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { UseIdentityUrlProps } from './identity-url.interfaces'
import type { UseIdentityUrlProps } from './identity-url.interfaces.js'

import { useState } from 'react'
import { getDomain } from 'tldjs'
import tldjs from 'tldjs'

import { useBrowserEffect } from './use-browser-effect.hook'
import { useBrowserEffect } from './use-browser-effect.hook.js'

export const identityUrlTypes = {
login: '/auth/login',
Expand All @@ -25,7 +25,7 @@ export const useIdentityUrl = ({ type = 'login', returnTo = false }: UseIdentity
if (hostname === 'localhost') {
setUrl(`${protocol}//localhost:3000${path}`)
} else {
const domain = getDomain(hostname)
const domain = tldjs.getDomain(hostname)

if (returnTo === false) {
setUrl(`${protocol}//accounts.${domain}${path}`)
Expand Down
2 changes: 1 addition & 1 deletion packages/react-kratos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@ory/kratos-client-fetch": "26.2.0",
"@testing-library/react": "16.1.0",
"@types/node": "^22.10.1",
"@types/react": "^18.2.45",
"@types/react": "18.3.6",
"@types/react-dom": "^18.2.18",
"global-jsdom": "25.0.0",
"jsdom": "25.0.1",
Expand Down
Loading
Loading