Browse Source

Broke out requests into another file

wip/alt-interface
Jared 1 year ago
parent
commit
6e24c84cb6
10 changed files with 191 additions and 132 deletions
  1. +105
    -0
      src/api/composed.ts
  2. +14
    -9
      src/api/requests.ts
  3. +8
    -11
      src/components/EditQueue.vue
  4. +1
    -2
      src/router/index.ts
  5. +21
    -21
      src/views/AddFundView.vue
  6. +24
    -61
      src/views/FundView.vue
  7. +6
    -10
      src/views/HomeView.vue
  8. +2
    -8
      src/views/LoginView.vue
  9. +2
    -9
      src/views/RegisterView.vue
  10. +8
    -1
      tests/unit/example.spec.ts

+ 105
- 0
src/api/composed.ts View File

@@ -0,0 +1,105 @@
import SignetRequestController from '@/api/requests';
import {
AuthenticationRequest,
Bonus,
CloseRewardFundRequest,
ContributeRequest,
CreateQueueRequest,
CreateQueueResponse,
CreateRewardFundRequest,
GetBalanceRequest,
GetBalanceResponse,
GetContributionsRequest,
GetContributionsResponse,
GetQueueMembersRequest,
GetQueueMembersResponse,
GetQueuesResponse,
GetRewardFundRequest,
GetRewardFundResponse,
GetRewardFundsRequest,
GetRewardFundsResponse,
LoginResponse,
SuccessResponse,
} from '@/api/types';

const controller = new SignetRequestController();

export const register = (username: string, password: string) => controller.post<SuccessResponse, AuthenticationRequest>('Register', {
username,
password,
});

export const login = (username: string, password: string) => controller.post<LoginResponse, AuthenticationRequest>('Login', {
username,
password,
});

export const getRewardFunds = (offset: number) => controller.post<GetRewardFundsResponse, GetRewardFundsRequest>('GetRewardFunds', { offset });

export const getQueues = () => controller.post<GetQueuesResponse, null>('GetQueues', null);

export const getQueueMembers = (id: number) => controller.post<GetQueueMembersResponse, GetQueueMembersRequest>('GetQueueMembers', { id });

export const createQueue = (name: string) => controller.post<CreateQueueResponse, CreateQueueRequest>('CreateQueue', { name });

export const createRewardFund = (
asset: string,
fundWallet: string,
sellingWallet: string,
issuerWallet: string,
memo: string,
minContribution: number,
title: string,
description: string,
bonuses: Bonus[],
queueID?: number | null | undefined,
) => controller.post<SuccessResponse, CreateRewardFundRequest>('CreateRewardFund', {
asset,
fundWallet,
sellingWallet,
issuerWallet,
memo,
minContribution,
title,
description,
bonuses,
queueID,
});

export const deleteRewardFund = (id: number, close: boolean) => controller.post<
SuccessResponse, CloseRewardFundRequest
>(
'CloseRewardFund',
{
id,
close,
},
);

export const getRewardFund = (id: number, consolidateContributions: boolean) => controller.post<GetRewardFundResponse, GetRewardFundRequest>('GetRewardFund', {
id,
consolidateContributions,
});

export const getContributions = (
id: number,
offset: number,
forDate: string | undefined,
consolidateContributions: boolean,
) => controller.post<GetContributionsResponse, GetContributionsRequest>(
'GetContributions',
{
id,
offset,
forDate,
consolidateContributions,
},
);

export const getBalance = (secretKey: string) => controller.post<GetBalanceResponse, GetBalanceRequest>('GetBalance', { secretKey });

export const contribute = (privateKey: string, amount: number, rewardFund: number) => controller.post<SuccessResponse, ContributeRequest>('Contribute', {
privateKey,
amount,
rewardFund,
});

+ 14
- 9
src/api/requests.ts View File

@@ -1,3 +1,5 @@
import store from '@/store';

const setHeaders = (headers: HeadersInit | undefined, token: string | undefined) => { const setHeaders = (headers: HeadersInit | undefined, token: string | undefined) => {
if (!headers && !!token) { if (!headers && !!token) {
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
@@ -6,24 +8,24 @@ const setHeaders = (headers: HeadersInit | undefined, token: string | undefined)
return headers; return headers;
} }
if (!!headers && !!token) { if (!!headers && !!token) {
return { ...headers, Authorization: `Bearer ${token}` };
return {
...headers,
Authorization: `Bearer ${token}`,
};
} }
return {}; return {};
}; };


class SignetRequestController { class SignetRequestController {
token?: string = undefined;

constructor(token?: string) {
this.token = token;
}

get = async <T>(endpoint: string): Promise<T | null> => { get = async <T>(endpoint: string): Promise<T | null> => {
const resp = await fetch( const resp = await fetch(
`/api/${endpoint}`, `/api/${endpoint}`,
{ {
method: 'GET', method: 'GET',
headers: setHeaders(undefined, this.token),
headers: setHeaders(
undefined,
store.getters.getToken,
),
}, },
); );
if (resp.status === 404) { if (resp.status === 404) {
@@ -38,7 +40,10 @@ class SignetRequestController {
{ {
method: 'POST', method: 'POST',
body: JSON.stringify(payload), body: JSON.stringify(payload),
headers: setHeaders({ 'Content-Type': 'application/json' }, this.token),
headers: setHeaders(
{ 'Content-Type': 'application/json' },
store.getters.getToken,
),
}, },
); );
if (resp.status === 404) { if (resp.status === 404) {


+ 8
- 11
src/components/EditQueue.vue View File

@@ -47,17 +47,14 @@ import {
watch, watch,
} from 'vue'; } from 'vue';
import { import {
GetQueueMembersRequest,
GetQueueMembersResponse,
GetQueuesResponse,
Queue, Queue,
RewardFund, RewardFund,
} from '@/api/types'; } from '@/api/types';
import Draggable from 'vuedraggable'; import Draggable from 'vuedraggable';
import SignetRequestController from '@/api/requests';
import store from '@/store';
const controller = new SignetRequestController(store.getters.getToken);
import {
getQueueMembers,
getQueues,
} from '@/api/composed';


// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(['selected', 'created']); const emits = defineEmits(['selected', 'created']);
@@ -69,9 +66,9 @@ const drag = ref(false);


const queues = ref([] as Queue[]); const queues = ref([] as Queue[]);
const fetchQueues = async () => { const fetchQueues = async () => {
const v = await controller.post<GetQueuesResponse, null>('GetQueues', null);
if (v) {
queues.value = v.queues;
const resp = await getQueues();
if (resp) {
queues.value = resp.queues;
} }
}; };


@@ -86,7 +83,7 @@ const createdQueue = () => {
}; };


const populateQueueMembers = async (id: number) => { const populateQueueMembers = async (id: number) => {
const resp = await controller.post<GetQueueMembersResponse, GetQueueMembersRequest>('GetQueueMembers', { id });
const resp = await getQueueMembers(id);
queueMembers.value = resp?.members; queueMembers.value = resp?.members;
}; };




+ 1
- 2
src/router/index.ts View File

@@ -14,7 +14,6 @@ import FundView from '@/views/FundView.vue';
import AddFundView from '@/views/AddFundView.vue'; import AddFundView from '@/views/AddFundView.vue';
import hasPermission from '@/lib/auth'; import hasPermission from '@/lib/auth';
import SignetRequestController from '@/api/requests'; import SignetRequestController from '@/api/requests';
import store from '@/store';


const routes: Array<RouteRecordRaw> = [ const routes: Array<RouteRecordRaw> = [
{ {
@@ -42,7 +41,7 @@ const routes: Array<RouteRecordRaw> = [
meta: { meta: {
requiredRights: Privileges.AdminPlus, requiredRights: Privileges.AdminPlus,
accessible: async () => { accessible: async () => {
const controller = new SignetRequestController(store.getters.getToken);
const controller = new SignetRequestController();
const canProceed = await controller.post<SuccessResponse, null>('/UsersExist', null); const canProceed = await controller.post<SuccessResponse, null>('/UsersExist', null);
return canProceed?.success; return canProceed?.success;
}, },


+ 21
- 21
src/views/AddFundView.vue View File

@@ -66,23 +66,23 @@
import SignetRequestController from '@/api/requests'; import SignetRequestController from '@/api/requests';
import { import {
Bonus, Bonus,
CreateQueueRequest,
CreateQueueResponse, CreateQueueResponse,
CreateRewardFundRequest,
SuccessResponse,
} from '@/api/types'; } from '@/api/types';
import { ref } from 'vue'; import { ref } from 'vue';
import store from '@/store';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import FundTierInput from '@/components/FundTierInput.vue'; import FundTierInput from '@/components/FundTierInput.vue';
import { sanitize } from '@/lib/helpers';
import EditQueue from '@/components/EditQueue.vue'; import EditQueue from '@/components/EditQueue.vue';
import {
createQueue,
createRewardFund,
} from '@/api/composed';
import { sanitize } from '@/lib/helpers';


const router = useRouter(); const router = useRouter();


document.title = 'Beignet - Add Fund'; document.title = 'Beignet - Add Fund';


const controller = new SignetRequestController(store.getters.getToken);
const controller = new SignetRequestController();


const title = ref(''); const title = ref('');
const description = ref(''); const description = ref('');
@@ -111,10 +111,10 @@ const saveBonuses = (evt: Bonus[]) => {
bonuses.value = evt; bonuses.value = evt;
}; };


const createQueue = async () => {
const doCreateQueue = async () => {
if (!queueName.value) return null; if (!queueName.value) return null;
const resp = ref(undefined as CreateQueueResponse | undefined); const resp = ref(undefined as CreateQueueResponse | undefined);
resp.value = await controller.post<CreateQueueResponse, CreateQueueRequest>('CreateQueue', { name: queueName.value }) ?? undefined;
resp.value = await createQueue(queueName.value) ?? undefined;
if (resp.value?.id) { if (resp.value?.id) {
return resp.value?.id; return resp.value?.id;
} }
@@ -129,22 +129,22 @@ const submit = async () => {
requesting.value = true; requesting.value = true;
const forQueue = ref(undefined as null | number | undefined); const forQueue = ref(undefined as null | number | undefined);
if (queueSelection.value === -1) { if (queueSelection.value === -1) {
forQueue.value = await createQueue();
forQueue.value = await doCreateQueue();
} else { } else {
forQueue.value = queueSelection.value; forQueue.value = queueSelection.value;
} }
const resp = await controller.post<SuccessResponse, CreateRewardFundRequest>('CreateRewardFund', {
asset: asset.value,
fundWallet: sanitize(fundWallet.value),
sellingWallet: sanitize(sellWallet.value),
issuerWallet: sanitize(issuerWallet.value),
memo: sanitize(memo.value),
minContribution: minContribution.value,
title: sanitize(title.value),
description: sanitize(description.value),
bonuses: bonuses.value,
queueID: forQueue.value,
});
const resp = await createRewardFund(
asset.value,
sanitize(fundWallet.value),
sanitize(sellWallet.value),
sanitize(issuerWallet.value),
sanitize(memo.value),
minContribution.value,
sanitize(title.value),
sanitize(description.value),
bonuses.value,
forQueue.value,
);
requesting.value = false; requesting.value = false;


if (!resp) throw new Error('Could not get response for fund creation'); if (!resp) throw new Error('Could not get response for fund creation');


+ 24
- 61
src/views/FundView.vue View File

@@ -193,18 +193,10 @@ import {
} from 'vue-router'; } from 'vue-router';
import { import {
Bonus, Bonus,
CloseRewardFundRequest,
ContributeRequest,
Contribution, Contribution,
FundInfo, FundInfo,
GetBalanceRequest,
GetBalanceResponse,
GetContributionsRequest,
GetContributionsResponse,
GetRewardFundRequest,
GetRewardFundResponse, GetRewardFundResponse,
Privileges, Privileges,
SuccessResponse,
} from '@/api/types'; } from '@/api/types';
import { import {
computed, computed,
@@ -213,7 +205,6 @@ import {
watch, watch,
} from 'vue'; } from 'vue';
import { useWebSocket } from '@vueuse/core'; import { useWebSocket } from '@vueuse/core';
import SignetRequestController from '@/api/requests';
import store from '@/store'; import store from '@/store';
import { import {
sanitize, sanitize,
@@ -222,8 +213,13 @@ import {
import * as luxon from 'luxon'; import * as luxon from 'luxon';
import hasPermission from '@/lib/auth'; import hasPermission from '@/lib/auth';
import ErrorDisplay, { SignetError } from '@/components/ErrorDisplay.vue'; import ErrorDisplay, { SignetError } from '@/components/ErrorDisplay.vue';

const controller = new SignetRequestController(store.getters.getToken);
import {
contribute,
deleteRewardFund,
getBalance,
getContributions,
getRewardFund,
} from '@/api/composed';


const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@@ -245,17 +241,9 @@ const selectedDate = ref(undefined as string | undefined);


const allowDelete = ref(false); const allowDelete = ref(false);
const deleteFund = async () => { const deleteFund = async () => {
if (allowDelete.value) {
const deleted = await controller.post<SuccessResponse, CloseRewardFundRequest>(
'CloseRewardFund',
{
id: identifier,
close: true,
},
);
if (deleted && deleted.success) {
await router.push('/');
}
const deleted = await deleteRewardFund(identifier, allowDelete.value);
if (deleted && deleted.success) {
await router.push('/');
} }
}; };


@@ -276,10 +264,7 @@ const fundDetails = ref([{
val: '', val: '',
}]); }]);


fund.value = await controller.post<GetRewardFundResponse, GetRewardFundRequest>('GetRewardFund', {
id: identifier,
consolidateContributions: enableConsolidation.value,
});
fund.value = await getRewardFund(identifier, enableConsolidation.value);
if (!fund.value) { if (!fund.value) {
router.push('/'); router.push('/');
throw new Error('Fund not found'); throw new Error('Fund not found');
@@ -394,17 +379,7 @@ document.title = `Beignet - ${fund.value.fundInfo.title}`;


watch(selectedDate, async (newVal) => { watch(selectedDate, async (newVal) => {
offset.value = 0; offset.value = 0;
const conts = await controller.post<
GetContributionsResponse, GetContributionsRequest
>(
'GetContributions',
{
id: identifier,
offset: offset.value,
forDate: newVal,
consolidateContributions: enableConsolidation.value,
},
);
const conts = await getContributions(identifier, offset.value, newVal, enableConsolidation.value);
if (!fund.value) throw new Error('Fund not found'); if (!fund.value) throw new Error('Fund not found');
if (!conts) throw new Error('Contributions not found'); if (!conts) throw new Error('Contributions not found');
contributions.value = conts.list; contributions.value = conts.list;
@@ -420,14 +395,11 @@ const loadMoreIfNeeded = async (e: Event) => {


if (canLoadMore()) { if (canLoadMore()) {
contributionsLoading.value = true; contributionsLoading.value = true;
const moreContribs = await controller.post<GetContributionsResponse, GetContributionsRequest>(
'GetContributions',
{
id: identifier,
offset: offset.value,
forDate: selectedDate.value,
consolidateContributions: enableConsolidation.value,
},
const moreContribs = await getContributions(
identifier,
offset.value,
selectedDate.value,
enableConsolidation.value,
); );
if (!moreContribs) throw new Error('Contributions not found'); if (!moreContribs) throw new Error('Contributions not found');
offset.value += moreContribs.list.length; offset.value += moreContribs.list.length;
@@ -451,7 +423,7 @@ const {
const queryAccount = async () => { const queryAccount = async () => {
if (pk.value && pk.value.startsWith('S')) { if (pk.value && pk.value.startsWith('S')) {
loading.value.balance = true; loading.value.balance = true;
const resp = await controller.post<GetBalanceResponse, GetBalanceRequest>('GetBalance', { secretKey: pk.value });
const resp = await getBalance(pk.value);
if (resp === null) { if (resp === null) {
unknownAcct.value = true; unknownAcct.value = true;
acctBalance.value = undefined; acctBalance.value = undefined;
@@ -475,11 +447,7 @@ const makeContribution = async () => {
if (unknownAcct.value) return; if (unknownAcct.value) return;
if (!loading.value.contribution && pk.value && amt.value && amt.value <= amountAvailable.value) { if (!loading.value.contribution && pk.value && amt.value && amt.value <= amountAvailable.value) {
loading.value.contribution = true; loading.value.contribution = true;
await controller.post<SuccessResponse, ContributeRequest>('Contribute', {
privateKey: sanitize(pk.value),
amount: amt.value,
rewardFund: fund.value.fundInfo.id,
});
await contribute(sanitize(pk.value), amt.value, fund.value.fundInfo.id);
loading.value.contribution = false; loading.value.contribution = false;
pk.value = ''; pk.value = '';
amt.value = undefined; amt.value = undefined;
@@ -488,16 +456,11 @@ const makeContribution = async () => {


watch(enableConsolidation, async () => { watch(enableConsolidation, async () => {
offset.value = 0; offset.value = 0;
const conts = await controller.post<
GetContributionsResponse, GetContributionsRequest
>(
'GetContributions',
{
id: identifier,
offset: offset.value,
forDate: selectedDate.value,
consolidateContributions: enableConsolidation.value,
},
const conts = await getContributions(
identifier,
offset.value,
selectedDate.value,
enableConsolidation.value,
); );
if (!fund.value) throw new Error('Fund not found'); if (!fund.value) throw new Error('Fund not found');
if (!conts) throw new Error('Contributions not found'); if (!conts) throw new Error('Contributions not found');


+ 6
- 10
src/views/HomeView.vue View File

@@ -18,22 +18,18 @@
</template> </template>


<script setup lang="ts"> <script setup lang="ts">
import {
GetRewardFundsRequest,
GetRewardFundsResponse,
} from '@/api/types';
import { ref } from 'vue'; import { ref } from 'vue';
import SignetRequestController from '@/api/requests';
import store from '@/store';
import FundLink from '@/components/FundLink.vue'; import FundLink from '@/components/FundLink.vue';

const controller = new SignetRequestController(store.getters.getToken);
import { getRewardFunds } from '@/api/composed';


const offset = ref(0); const offset = ref(0);


const response = await controller.post<GetRewardFundsResponse, GetRewardFundsRequest>('GetRewardFunds', { offset: offset.value });
const response = await getRewardFunds(offset.value);
if (!response) throw new Error('Could not get reward funds'); if (!response) throw new Error('Could not get reward funds');
const { total, rewardFunds } = response;
const {
total,
rewardFunds,
} = response;
offset.value = total; offset.value = total;
</script> </script>




+ 2
- 8
src/views/LoginView.vue View File

@@ -21,13 +21,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import store from '@/store'; import store from '@/store';
import {
AuthenticationRequest,
LoginResponse,
} from '@/api/types';
import SignetRequestController from '@/api/requests';

const controller = new SignetRequestController(store.getters.getToken);
import { login } from '@/api/composed';


const router = useRouter(); const router = useRouter();


@@ -35,7 +29,7 @@ const username = ref('');
const password = ref(''); const password = ref('');


const submit = async () => { const submit = async () => {
const resp = await controller.post<LoginResponse, AuthenticationRequest>('Login', { username: username.value, password: password.value });
const resp = await login(username.value, password.value);
if (!resp) throw new Error('Could not get response from login'); if (!resp) throw new Error('Could not get response from login');
if (resp.token !== null) { if (resp.token !== null) {
sessionStorage.setItem('jwt', JSON.stringify({ token: resp.token })); sessionStorage.setItem('jwt', JSON.stringify({ token: resp.token }));


+ 2
- 9
src/views/RegisterView.vue View File

@@ -19,15 +19,8 @@


<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import {
AuthenticationRequest,
SuccessResponse,
} from '@/api/types';
import SignetRequestController from '@/api/requests';
import store from '@/store';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';

const controller = new SignetRequestController(store.getters.getToken);
import { register } from '@/api/composed';


const router = useRouter(); const router = useRouter();


@@ -36,7 +29,7 @@ const password = ref('');
const success = ref(false); const success = ref(false);


const submit = async () => { const submit = async () => {
const resp = await controller.post<SuccessResponse, AuthenticationRequest>('Register', { username: username.value, password: password.value });
const resp = await register(username.value, password.value);
if (!resp) throw new Error('Could not get response from registration'); if (!resp) throw new Error('Could not get response from registration');
success.value = resp.success; success.value = resp.success;
if (success.value) { if (success.value) {


+ 8
- 1
tests/unit/example.spec.ts View File

@@ -2,12 +2,19 @@ import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue'; import HelloWorld from '@/components/HelloWorld.vue';


// TODO: Not sure why this isn't working
// vi.mock('@/api/composed', () => ({
// getRewardFunds: vi.fn(() => []),
// }));

describe('HelloWorld.vue', () => { describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => { it('renders props.msg when passed', () => {
const msg = 'new message'; const msg = 'new message';
const wrapper = shallowMount(HelloWorld, { const wrapper = shallowMount(HelloWorld, {
props: { msg }, props: { msg },
}); });
expect(wrapper.text()).to.include(msg);
expect(wrapper.text())
.to
.include(msg);
}); });
}); });

Loading…
Cancel
Save