Skip to content

Commit

Permalink
feat(Input): show fluus left today
Browse files Browse the repository at this point in the history
  • Loading branch information
jkklapp committed Jun 5, 2022
1 parent 3a864b7 commit c534522
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 17 deletions.
23 changes: 13 additions & 10 deletions backend/src/posts/controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ jest.mock('./utils', () => {
describe('Controller', () => {
let c: Controller;
let s: Service;
let old_env;

beforeEach(() => {
const collection = null;
s = new Service(collection);
c = new Controller(s);
old_env = process.env;
process.env = { MAX_NUMBER_POSTS_PER_DAY: '5' };
jest.spyOn(s, 'countAllforUserByDate').mockResolvedValue(0);
});
afterEach(() => {
process.env = old_env;
jest.restoreAllMocks();
});

describe('getMultiple', () => {
it('should return an array of ', async () => {
const result = {
Expand All @@ -30,14 +37,18 @@ describe('Controller', () => {
userId: '1234',
},
],
remainingMessages: 10,
nextPageToken: null,
};
jest
.spyOn(s, 'getMultiple')
.mockImplementation(() => Promise.resolve(result));

expect(await c.getMultiple(10, null)).toEqual({
expect(
await c.getMultiple({ user: { user_id: '1234' } }, 10, null),
).toEqual({
nextPageToken: null,
remainingMessages: 5,
results: [
{
date: 100000,
Expand All @@ -57,7 +68,6 @@ describe('Controller', () => {
userId: '1234',
userName: 'Test',
});
jest.spyOn(s, 'countAllforUserByDate').mockResolvedValue(0);
});
it('should return a new post', async () => {
expect(
Expand All @@ -70,16 +80,9 @@ describe('Controller', () => {
});
});
describe('when the user has reached the max number of posts per day', () => {
let old_env;
beforeEach(() => {
old_env = process.env;
process.env = { MAX_NUMBER_POSTS_PER_DAY: '5' };
jest.spyOn(s, 'countAllforUserByDate').mockResolvedValue(5);
});
afterEach(() => {
process.env = old_env;
jest.restoreAllMocks();
});
it('should throw an error', async () => {
await expect(
c.create({ user: { user_id: '1234' } }, { message: 'test' }),
Expand Down
14 changes: 14 additions & 0 deletions backend/src/posts/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class Controller {
@Get()
@UseGuards(FirebaseAuthGuard)
public async getMultiple(
@Req() request: any,
@Query('limit', ParseIntPipe) limit: number,
@Query('startAfter') startAfter?: string,
): Promise<PostDocumentResult> {
Expand All @@ -40,8 +41,21 @@ export class Controller {
});
}

const { user } = request;
const { user_id: userId } = user;
const last24hours = Date.now() - 86400000;
const numberPostsCreatedToday = await this.service.countAllforUserByDate(
userId,
last24hours,
);
const maxNumberPostsPerDay = parseInt(
process.env.MAX_NUMBER_POSTS_PER_DAY,
10,
);

return {
results: resolvedPosts.slice(),
remainingMessages: maxNumberPostsPerDay - numberPostsCreatedToday,
nextPageToken,
};
}
Expand Down
8 changes: 6 additions & 2 deletions backend/src/posts/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ export class PostDocument extends NewPostDocument {
id?: string;
}

export class PostDocumentResult {
export class PaginatedResults {
results: PostDocument[];
nextPageToken?: number;
nextPageToken: number | null;
}

export class PostDocumentResult extends PaginatedResults {
remainingMessages: number;
}

export class ResolvedPostDocument extends PostDocument {
Expand Down
4 changes: 2 additions & 2 deletions backend/src/posts/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as dayjs from 'dayjs';
import { CollectionReference } from '@google-cloud/firestore';
import {
PostDocument,
PostDocumentResult,
PaginatedResults,
ResolvedPostDocument,
} from './document';

Expand All @@ -19,7 +19,7 @@ export class Service {
async getMultiple(
limit: number,
startAfter?: string | undefined,
): Promise<PostDocumentResult> {
): Promise<PaginatedResults> {
const _startAfter = startAfter ? parseInt(startAfter, 10) : '';
const noMoreResults = startAfter ? -1 : null;
return this.postsCollection
Expand Down
1 change: 1 addition & 0 deletions frontend/.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
VUE_APP_SUPPORT_EMAIL=jkk.lapp@gmail.com
VUE_APP_MESSAGE_NAME=fluu
VUE_APP_BASE_URL=https://fluunker.com
VUE_APP_NAME=Fluunker
VUE_APP_INPUT_LABEL=Fluunk
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/Dashboard/Input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const mountComponent = (isPosting = false) => {
computed: {
inputLabel: () => 'Fluunk',
inputCtaLabel: () => 'Fluu',
placeholder: () => 'You have 10 left',
isInputDisabled: () => isPosting,
isPosting: {
get() {
return isPosting;
Expand All @@ -37,6 +39,12 @@ describe('Input', () => {
afterEach(() => {
jest.resetAllMocks();
});
it('has a placeholder with the number of messages left', () => {
const wrapper = mountComponent();
expect(wrapper.find('input').attributes('placeholder')).toBe(
'You have 10 left',
);
});
it('can input message in input field', () => {
const wrapper = mountComponent();

Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/Dashboard/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
</div>
<input
v-model="message"
:placeholder="[[placeholder]]"
class="block p-4 pl-10 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
@keyup.enter="submit"
/>
<button
class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
:disabled="isPosting"
:disabled="isInputDisabled"
@click.prevent="submit"
>
{{ inputCtaLabel }}
Expand All @@ -52,9 +53,16 @@ export default {
computed: {
inputLabel: () => process.env.VUE_APP_INPUT_LABEL,
inputCtaLabel: () => process.env.VUE_APP_INPUT_CTA_LABEL,
placeholder() {
return `You have ${this.remainingMessages} ${process.env.VUE_APP_MESSAGE_NAME}s left today`;
},
isInputDisabled() {
return this.isPosting || this.remainingMessages === 0;
},
...mapGetters({
posts: 'getPosts',
isPosting: 'isCreatingPost',
remainingMessages: 'getRemainingMessages',
}),
},
methods: {
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/store/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ export default {
startAfter,
limit,
});
const { results, nextPageToken } = data;
const { results, nextPageToken, remainingMessages } = data;
commit('SET_POSTS', results);
commit('SET_START_AFTER', nextPageToken);
commit('SET_REMAINING_MESSAGES', remainingMessages || 0);
commit('IS_LOADING_POSTS', false);
},
setMessage({ commit }, message) {
Expand All @@ -23,7 +24,7 @@ export default {
resetPostsPagination({ commit }) {
commit('SET_START_AFTER', null);
},
async postMessage({ commit }, message) {
async postMessage({ commit, state }, message) {
commit('IS_CREATING_POST', true);
commit('PUSH_MESSAGE', {
message,
Expand All @@ -33,6 +34,7 @@ export default {
const { data } = await apiRequest('POST', '/posts', null, { message });
commit('POP_MESSAGE');
commit('PUSH_MESSAGE', data);
commit('SET_REMAINING_MESSAGES', state.remainingMessages - 1);
} catch ({ response }) {
commit('POP_MESSAGE');
throw response.data;
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/store/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ export default {
isCreatingPost(state) {
return state.creatingPost;
},
getRemainingMessages(state) {
return state.remainingMessages;
},
};
1 change: 1 addition & 0 deletions frontend/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const store = createStore({
loadingPosts: false,
creatingPost: false,
loggedIn: false,
remainingMessages: 0,
},
getters,
mutations,
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export default {
SET_START_AFTER(state, data) {
state.startAfter = data;
},
SET_REMAINING_MESSAGES(state, data) {
state.remainingMessages = data;
},
PUSH_MESSAGE(state, data) {
state.posts = [
{ ...data, userName: state.user.displayName },
Expand Down

0 comments on commit c534522

Please sign in to comment.