Skip to content

Commit

Permalink
See minimal donation details on click
Browse files Browse the repository at this point in the history
also...
- load donations/requests on App load
- store configuration returns a function to avoid test pollution
  • Loading branch information
carpeliam committed Apr 22, 2020
1 parent 32e07d3 commit 4bca7b9
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 149 deletions.
112 changes: 62 additions & 50 deletions src/store/actions.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,5 @@
function initializeGoogleClient({ commit }) {
const updateSignInStatus = (isSignedIn) => commit(isSignedIn ? 'signIn' : 'signOut');

gapi.load('client:auth2', () => {
gapi.client.init({
apiKey: process.env.VUE_APP_API_KEY,
clientId: process.env.VUE_APP_CLIENT_ID,
discoveryDocs: ['https://sheets.googleapis.com/$discovery/rest?version=v4'],
scope: 'https://www.googleapis.com/auth/spreadsheets',
}).then(() => {
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSignInStatus);
updateSignInStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
});
});
}

function signIn() {
gapi.auth2.getAuthInstance().signIn();
}

function signOut() {
gapi.auth2.getAuthInstance().signOut();
}

async function fetch(commit, range, columns) {
const { result: { values } } = await gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: process.env.VUE_APP_SPREADSHEET_ID,
range,
});
const rowsWithoutHeader = values.slice(1);
const items = rowsWithoutHeader.map((row) => {
const item = {};
for (let i = 0; i < row.length; i += 1) {
item[columns[i]] = row[i];
}
return item;
});
commit(`load${range}`, items);
}

export async function fetchRequests({ commit }) {
const REQUEST_COLS = [
const sheetsLayout = {
Requests: [
'id',
'dateRequested',
'status',
Expand All @@ -55,12 +15,8 @@ export async function fetchRequests({ commit }) {
'recurrenceFrequency',
'assigned',
'notes',
];
fetch(commit, 'Requests', REQUEST_COLS);
}

export async function fetchDonations({ commit }) {
const DONATION_COLS = [
],
Donations: [
'id',
'dateReceived',
'status',
Expand All @@ -76,8 +32,64 @@ export async function fetchDonations({ commit }) {
'recurranceFrequency',
'assigned',
'notes',
];
fetch(commit, 'Donations', DONATION_COLS);
],
};

function signIn() {
gapi.auth2.getAuthInstance().signIn();
}

function signOut() {
gapi.auth2.getAuthInstance().signOut();
}

async function fetch(commit, range) {
const columns = sheetsLayout[range];
const { result: { values } } = await gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: process.env.VUE_APP_SPREADSHEET_ID,
range,
});
const rowsWithoutHeader = values.slice(1);
const items = rowsWithoutHeader.map((row) => {
const item = {};
for (let i = 0; i < row.length; i += 1) {
item[columns[i]] = row[i];
}
return item;
});
commit(`load${range}`, items);
}

export async function fetchRequests({ commit }) {
fetch(commit, 'Requests');
}

export async function fetchDonations({ commit }) {
fetch(commit, 'Donations');
}

export function initializeGoogleClient({ commit }) {
const updateSignInStatus = (isSignedIn) => {
commit(isSignedIn ? 'signIn' : 'signOut');
if (isSignedIn) {
fetchRequests({ commit });
fetchDonations({ commit });
} else {
commit('clearSheetsData');
}
};

gapi.load('client:auth2', () => {
gapi.client.init({
apiKey: process.env.VUE_APP_API_KEY,
clientId: process.env.VUE_APP_CLIENT_ID,
discoveryDocs: ['https://sheets.googleapis.com/$discovery/rest?version=v4'],
scope: 'https://www.googleapis.com/auth/spreadsheets',
}).then(() => {
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSignInStatus);
updateSignInStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
});
});
}


Expand Down
4 changes: 2 additions & 2 deletions src/store/configuration.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import actions from './actions';
import mutations from './mutations';

export default {
export default () => ({
state: {
isSignedIn: false,
requests: [],
donations: [],
},
actions,
mutations,
};
});
2 changes: 1 addition & 1 deletion src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import configuration from './configuration';

Vue.use(Vuex);

export default new Vuex.Store(configuration);
export default new Vuex.Store(configuration());
4 changes: 4 additions & 0 deletions src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ export default {
loadDonations(state, donations) {
state.donations = donations;
},
clearSheetsData(state) {
state.requests = undefined;
state.donations = undefined;
},
};
31 changes: 24 additions & 7 deletions src/views/DonationList.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
<template>
<div>
<div class="donation-list">
<ul>
<li v-for="donation in donations" :key="donation.id">
{{donation.donorName}}
<li v-for="donation in donations" :key="donation.id" @click="focusOnDonation(donation)">
<div>{{donation.category}}</div>
<div>{{donation.subCategory}}</div>
<div>{{donation.donorName}}</div>
</li>
</ul>
<div class="donation-details" v-if="focusedDonation">
{{focusedDonation.details}}
</div>
<div></div>
</div>
</template>

<script>
import { mapActions, mapState } from 'vuex';
import { mapState } from 'vuex';
export default {
name: 'donation-list',
mounted() {
this.fetchDonations();
data() {
return {
focusedDonation: undefined,
};
},
computed: mapState(['donations']),
methods: {
...mapActions(['fetchDonations']),
focusOnDonation(donation) {
this.focusedDonation = donation;
},
},
};
</script>

<style lang="scss" scoped>
.donation-list {
display: grid;
grid-template-columns: 2fr 5fr 5fr;
}
</style>
8 changes: 1 addition & 7 deletions src/views/RequestList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,10 @@
</template>

<script>
import { mapActions, mapState } from 'vuex';
import { mapState } from 'vuex';
export default {
name: 'request-list',
mounted() {
this.fetchRequests();
},
computed: mapState(['requests']),
methods: {
...mapActions(['fetchRequests']),
},
};
</script>
2 changes: 1 addition & 1 deletion tests/unit/App.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('App.vue', () => {

beforeEach(() => {
global.gapi = fakeGoogleApi();
store = new Vuex.Store(configuration);
store = new Vuex.Store(configuration());
});
afterEach(() => { delete global.gapi; });

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/components/SignIn.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('SignIn.vue', () => {

beforeEach(() => {
global.gapi = fakeGoogleApi();
store = new Vuex.Store(configuration);
store = new Vuex.Store(configuration());
});
afterEach(() => { delete global.gapi; });

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function googleAuth() {
}

function googleSpreadsheets() {
const sheetValues = {};
const sheetValues = { Donations: [], Requests: [] };
return {
sheets: {
spreadsheets: {
Expand Down
87 changes: 52 additions & 35 deletions tests/unit/store/actions.spec.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,61 @@
import sinon from 'sinon';
import { fetchRequests } from '@/store/actions';
import { initializeGoogleClient, fetchRequests } from '@/store/actions';
import { expect, fakeGoogleApi } from '../helpers';

describe('actions', () => {
describe('fetchRequests', () => {
beforeEach(() => {
global.gapi = fakeGoogleApi();
gapi.fake.spreadsheets.addValue('Requests', [
[
'Request ID',
'Date requested',
'Status',
'Request Urgency',
'Requester Name',
'Requester ID',
'Request Category',
'Request Sub-category',
'Request Details',
'Request Location',
'Fulfilled by',
'Date Fulfilled',
'Recurrance frequency',
'Assigned',
'Notes',
],
[
'1',
'3/25/20',
'Requested',
'Low',
'Somerville High School',
'1',
'Food items',
'Hot meals',
'We need hot meals',
],
]);
beforeEach(() => {
global.gapi = fakeGoogleApi();
gapi.fake.spreadsheets.addValue('Donations', [
[
'Donation ID', 'Date Received', 'Status', 'Donation Urgency', 'Donor Name', 'Donor ID',
'Donation Category', 'Donation Sub - category', 'Donation Details', 'Donation Location',
'Recipient', 'Date deployed', 'Recurrance frequency', 'Assigned', 'Notes',
],
[
'1', '3/24/2020', 'Inbound', 'High', 'Baldor Boston', '1', 'Food items', 'Hot meals', 'I can make 5000 hot meals for SHS students',
],
]);
gapi.fake.spreadsheets.addValue('Requests', [
[
'Request ID', 'Date requested', 'Status', 'Request Urgency', 'Requester Name',
'Requester ID', 'Request Category', 'Request Sub-category', 'Request Details',
'Request Location', 'Fulfilled by', 'Date Fulfilled', 'Recurrance frequency', 'Assigned',
'Notes',
],
[
'1', '3/25/20', 'Requested', 'Low', 'Somerville High School', '1', 'Food items', 'Hot meals', 'We need hot meals',
],
]);
});
afterEach(() => { delete global.gapi; });

describe('initializeGoogleClient', () => {
describe('upon signing in', () => {
beforeEach(() => {
gapi.fake.updateIsSignedIn(true);
});

it('fetches requests and donations', async () => {
await initializeGoogleClient({ commit: sinon.spy() });
expect(gapi.client.sheets.spreadsheets.values.get).to.have.been.calledWith({ spreadsheetId: 'FAKE_SPREADSHEET_ID', range: 'Requests' });
expect(gapi.client.sheets.spreadsheets.values.get).to.have.been.calledWith({ spreadsheetId: 'FAKE_SPREADSHEET_ID', range: 'Donations' });
});
});
afterEach(() => { delete global.gapi; });

describe('upon signing out', () => {
beforeEach(() => {
gapi.fake.updateIsSignedIn(false);
});
it('clears requests and donations', async () => {
const commit = sinon.spy();
await initializeGoogleClient({ commit });
expect(commit).to.have.been.calledWith('clearSheetsData');
expect(gapi.client.sheets.spreadsheets.values.get).not.to.have.been.called();
});
});
});

describe('fetchRequests', () => {
it('commits the requests', async () => {
const commit = sinon.spy();
await fetchRequests({ commit });
Expand Down
30 changes: 19 additions & 11 deletions tests/unit/views/DonationList.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,30 @@ describe('DonationList.vue', () => {

beforeEach(() => {
global.gapi = fakeGoogleApi();
gapi.fake.spreadsheets.addValue('Donations', [
[
'Donation ID', 'Date Received', 'Status', 'Donation Urgency', 'Donor Name', 'Donor ID',
'Donation Category', 'Donation Sub - category', 'Donation Details', 'Donation Location',
'Recipient', 'Date deployed', 'Recurrance frequency', 'Assigned', 'Notes',
store = new Vuex.Store(configuration());
store.replaceState({
donations: [
{
donorName: 'Baldor Boston',
details: 'I can make 5000 hot meals',
},
],
[
'1', '3/24/2020', 'Inbound', 'High', 'Baldor Boston', '1', 'Food items', 'Hot meals', 'I can make 5000 hot meal for SHS students',
],
]);
store = new Vuex.Store(configuration);
});
});
afterEach(() => { delete global.gapi; });
it('loads a list of donations on mount', async () => {

it('displays a list of donations', async () => {
const wrapper = render();
await wrapper.vm.$nextTick();
expect(wrapper.text()).to.contain('Baldor Boston');
});

describe('focusing on a donation', () => {
it('loads that donation in a new panel', async () => {
const wrapper = render();
wrapper.find('li').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('.donation-details').text()).to.contain('I can make 5000 hot meals');
});
});
});
Loading

0 comments on commit 4bca7b9

Please sign in to comment.