Skip to content

Commit

Permalink
Merge pull request #68 from FusionAuth/67-vue-add-sdkcontext-and-sdkc…
Browse files Browse the repository at this point in the history
…onfig

Bring Vue SDK to parity with React
  • Loading branch information
JakeLo123 authored Apr 25, 2024
2 parents 7a25bab + 1337409 commit a669565
Show file tree
Hide file tree
Showing 29 changed files with 502 additions and 185 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './SDKCore';
export * from './SDKConfig';
export * from './SDKContext';
export * from './testUtils';
//
export * from './CookieHelpers';
export * from './UrlHelper';
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/testUtils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './mockLoggedIn';
export * from './mockWindowLocation';
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { vi } from 'vitest';
import { VitestUtils } from 'vitest';

function mockWindowLocation() {
function mockWindowLocation(vi: VitestUtils) {
const mockedLocation = {
...window.location,
assign: vi.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import {
import { FusionAuthProviderConfig } from './FusionAuthProviderConfig';
import { UserInfo } from './Context';

import { mockWindowLocation } from '#/testing-tools/mocks/mockWindowLocation';
import { TEST_CONFIG } from '#testing-tools/mocks/testConfig';
import {
mockIsLoggedIn,
removeAt_expCookie,
} from '#/testing-tools/mocks/mockLoggedIn';
mockWindowLocation,
} from '@fusionauth-sdk/core';
import { TEST_CONFIG } from '#testing-tools/mocks/testConfig';

function renderWithWrapper(config: FusionAuthProviderConfig) {
return renderHook(() => useFusionAuth(), {
Expand All @@ -32,7 +32,7 @@ describe('FusionAuthProvider', () => {
});

test('Redirects to the correct login url', () => {
const mockedLocation = mockWindowLocation();
const mockedLocation = mockWindowLocation(vi);

const { result } = renderWithWrapper(TEST_CONFIG);

Expand All @@ -49,7 +49,7 @@ describe('FusionAuthProvider', () => {
});

test('Redirects to the correct logout url', () => {
const mockedLocation = mockWindowLocation();
const mockedLocation = mockWindowLocation(vi);

const { result } = renderWithWrapper(TEST_CONFIG);

Expand All @@ -67,7 +67,7 @@ describe('FusionAuthProvider', () => {
});

test('Redirects to the correct register url with `state` value echoed back.', () => {
const mockedLocation = mockWindowLocation();
const mockedLocation = mockWindowLocation(vi);

const { result } = renderWithWrapper(TEST_CONFIG);

Expand Down
13 changes: 6 additions & 7 deletions packages/sdk-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,22 @@
"vitest": "^1.3.1",
"vue": "^3.0.0",
"vue-docgen-web-types": "0.1.8",
"vue-tsc": "^1.8.5"
"vue-tsc": "^1.8.5",
"@fusionauth-sdk/core": "*"
},
"dependencies": {
"query-string": "8.1.0",
"@fusionauth-sdk/core": "*"
"query-string": "8.1.0"
},
"files": [
"dist/*"
],
"types": "./dist/src/index.d.ts",
"types": "./dist/index.d.ts",
"main": "./dist/vue-fusionauth.js",
"module": "./dist/vue-fusionauth.js",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/vue-fusionauth.js",
"require": "./dist/vue-fusionauth.umd.cjs"
"types": "./dist/index.d.ts",
"import": "./dist/vue-fusionauth.js"
},
"./dist/*.css": {
"import": "./dist/*.css",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { describe, expect, it } from 'vitest';
import { shallowMount } from '@vue/test-utils';
import { getMockFusionAuth } from '../../utilsForTests';

const stateValue = 'login-state-value';
const setup = () => {
const { key, mockedValues } = getMockFusionAuth({});
return [
shallowMount(FusionAuthLoginButton, {
props: { state: stateValue },
global: {
provide: {
[key]: mockedValues,
Expand All @@ -21,15 +23,15 @@ const setup = () => {
};

describe('FusionAuthLoginButton', () => {
it('renders with label', async () => {
it('renders with label', () => {
// Test
const [Button] = setup();

// Assert
expect(Button.text()).toBe('Label');
});

it('can be clicked to run login()', async () => {
it('can be clicked to run login()', () => {
// Setup
const [Button, { login }] = setup();

Expand All @@ -38,5 +40,6 @@ describe('FusionAuthLoginButton', () => {

// Assert
expect(login).toHaveBeenCalledOnce();
expect(login).toHaveBeenCalledWith(stateValue);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</template>

<script setup lang="ts">
import { useFusionAuth } from '../../composables/useFusionAuth';
import { useFusionAuth } from '#/composables/useFusionAuth';
const fusionAuth = useFusionAuth();
Expand All @@ -19,7 +19,7 @@ function doLogin() {
</script>

<style lang="scss" scoped>
@import '../../styles/button.scss';
@import '#/styles/button.scss';
.login-button {
@extend .fusionauth-button;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, expect, it } from 'vitest';
import { shallowMount } from '@vue/test-utils';

import FusionAuthLogoutButton from './FusionAuthLogoutButton.vue';
import { getMockFusionAuth } from '../../utilsForTests';

const label = 'logout button label';
const setup = () => {
const { key, mockedValues } = getMockFusionAuth({});
return [
shallowMount(FusionAuthLogoutButton, {
global: {
provide: {
[key]: mockedValues,
},
},
slots: {
default: label,
},
}),
mockedValues,
] as const;
};

describe('FusionAuthLogoutButton', () => {
it('renders with label', () => {
const [Button] = setup();
expect(Button.text()).toBe(label);
});

it('can be clicked to run logout()', () => {
const [Button, { logout }] = setup();
Button.trigger('click');
expect(logout).toHaveBeenCalledOnce();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</template>

<script setup lang="ts">
import { useFusionAuth } from '../composables/useFusionAuth.ts';
import { useFusionAuth } from '#/composables/useFusionAuth.ts';
const fusionAuth = useFusionAuth();
Expand All @@ -15,7 +15,7 @@ function doLogout() {
</script>

<style lang="scss" scoped>
@import '../styles/button.scss';
@import '#/styles/button.scss';
.logout-button {
@extend .fusionauth-button;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</template>

<script setup lang="ts">
import { useFusionAuth } from '../composables/useFusionAuth.ts';
import { useFusionAuth } from '#/composables/useFusionAuth.ts';
const fusionAuth = useFusionAuth();
Expand All @@ -19,7 +19,7 @@ function doRegister() {
</script>

<style lang="scss" scoped>
@import '../styles/button.scss';
@import '#/styles/button.scss';
.register-button {
@extend .fusionauth-button;
Expand Down
17 changes: 0 additions & 17 deletions packages/sdk-vue/src/components/RequireAnonymous.vue

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ref } from 'vue';
import { describe, expect, it } from 'vitest';
import { mount } from '@vue/test-utils';

import RequireAnonymous from './RequireAnonymous.vue';
import { getMockFusionAuth } from '../../utilsForTests';
import { FusionAuth } from '../../types';

function setup(params: {
fusionAuthMock: Partial<FusionAuth>;
content: string;
}) {
const { key, mockedValues } = getMockFusionAuth(params.fusionAuthMock);
return mount(RequireAnonymous, {
global: { provide: { [key]: mockedValues } },
slots: { default: params.content },
});
}

describe('RequireAnonymous', () => {
it('Renders the slot if not logged in', () => {
const content = 'There is content here';
const wrapper = setup({
fusionAuthMock: { isLoggedIn: ref(false) },
content,
});

expect(wrapper.text()).toBe(content);
});

it('Does not render the slot if logged in', () => {
const wrapper = setup({
fusionAuthMock: { isLoggedIn: ref(true) },
content: 'For admins only',
});

expect(wrapper.text()).toBe('');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<template v-if="!isLoggedIn">
<slot></slot>
</template>
</template>

<script setup lang="ts">
import { useFusionAuth } from '#/composables/useFusionAuth.ts';
const { isLoggedIn } = useFusionAuth();
</script>
42 changes: 0 additions & 42 deletions packages/sdk-vue/src/components/RequireAuth.vue

This file was deleted.

52 changes: 52 additions & 0 deletions packages/sdk-vue/src/components/RequireAuth/RequireAuth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ref } from 'vue';
import { describe, expect, it } from 'vitest';
import { mount } from '@vue/test-utils';

import RequireAuth from './RequireAuth.vue';
import { getMockFusionAuth } from '../../utilsForTests';
import { FusionAuth } from '../../types';

function setup(params: {
fusionAuthMock: Partial<FusionAuth>;
content: string;
withRole: string[];
}) {
const { key, mockedValues } = getMockFusionAuth(params.fusionAuthMock);

return mount(RequireAuth, {
global: { provide: { [key]: mockedValues } },
slots: { default: params.content },
props: {
withRole: params.withRole,
},
});
}

describe('RequireAuth', () => {
it('Renders the slot if the user is logged in with the specified role', () => {
const content = 'Protected Content';
const wrapper = setup({
fusionAuthMock: {
isLoggedIn: ref(true),
userInfo: ref({ roles: ['ADMIN'] }),
},
content,
withRole: ['USER', 'ADMIN'],
});

expect(wrapper.text()).toBe(content);
});

it('Does not render the slot if the user is not authorized', () => {
const wrapper = setup({
fusionAuthMock: {
isLoggedIn: ref(true),
userInfo: ref({ roles: ['USER'] }),
},
content: 'For admins only',
withRole: ['ADMIN', 'SUPER-ADMIN'],
});

expect(wrapper.text()).toBe('');
});
});
Loading

0 comments on commit a669565

Please sign in to comment.