Skip to content

Exercise 7#15

Open
ubiquitousbyte wants to merge 13 commits intomainfrom
exercise_7
Open

Exercise 7#15
ubiquitousbyte wants to merge 13 commits intomainfrom
exercise_7

Conversation

@ubiquitousbyte
Copy link
Copy Markdown
Contributor

@ubiquitousbyte ubiquitousbyte commented Jan 12, 2021

Pull request Group CountryRoads

@MaykAkifovski MaykAkifovski requested review from a team, aloparev and ilonae and removed request for roschaefer January 18, 2021 16:46
Copy link
Copy Markdown
Contributor

@aloparev aloparev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. You apparently did not implement the edit button, but since your delete works, it is not a big loss. And you even implemented the optional storybooks. However, I think the following files could be skipped from review: webapp/layouts/default.vue, webapp/test/NewsForm.test.js. Total result for objectives: 12/13 ⭐.

Comment thread webapp/components/login-form/LoginForm.vue
Comment thread webapp/components/menu/Menu.vue
Comment thread webapp/components/news-item/NewsItem.vue
Comment thread webapp/nuxt.config.js
Comment thread webapp/plugins/authPlugin.js
Comment thread webapp/test/LoginForm.test.js
Comment thread webapp/test/Menu.test.js
Comment thread webapp/README.md
Comment thread webapp/README.md
Copy link
Copy Markdown
Contributor

@roschaefer roschaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woohoo

This is an intermediate PR. I haven't tested out your code, just looked at the source code. To me, it looks as if you already rock GraphQL, NuxtJS, VueJS and Vuetify. Congrats

const mutation = gql`
mutation ($title: ID!) {
upvote(title: $title) {
votes
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request the ID here and let vue-apollo do all the work to update the Post object! 💪

mutation,
variables: { title: this.newsItem.title }
})
this.$emit('updateNews', {...this.newsItem, votes: upvote.votes});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove all code to update things that have been previously cached. vue-apollo will do it for you.

const variables = { post: { title } };
try {
const { data: { write } } = await this.$apollo.mutate({ mutation, variables })
this.newsItems.push({ title: write.title, votes: write.votes, author: write.author});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use update hook to update the cached posts query: https://apollo.vuejs.org/guide/apollo/mutations.html

Comment on lines +89 to +108
async getNews() {
const query = gql`
query {
posts {
title
votes
author {
id
}
}
}
`;
try {
const { data: { posts }} = await this.$apollo.query( { query } );
return posts;
}
catch (e) {
return [];
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async getNews() {
const query = gql`
query {
posts {
title
votes
author {
id
}
}
}
`;
try {
const { data: { posts }} = await this.$apollo.query( { query } );
return posts;
}
catch (e) {
return [];
}
}
apollo: {
posts: gql`
query {
posts {
title
votes
author {
id
}
}
}
`
}

Will automatically populate this.posts for you! 💪

https://apollo.vuejs.org/guide/apollo/#queries

Comment on lines +122 to +124
async mounted() {
this.newsItems = await this.getNews();
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async mounted() {
this.newsItems = await this.getNews();
},

Using queries according to the docs will work even in SSR. This mounted hook only runs client-side.

const [emailExists, emailIsNotTooLong] = wrapper.vm.nameRules

expect(emailExists(email)).toBe(true);
expect(emailIsNotTooLong(email)).toBe("User name cannot exceed 64 chars!");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you call it User name if it's the email? 🤔

it('keeps the login button disabled if the email is too long', async () => {
const email = 'testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest'
const submitButton = wrapper.find('#login');
const [emailExists, emailIsNotTooLong] = wrapper.vm.nameRules
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider wrapper.vm as private. If you want to unit test your validations, export them in your component:

<script>
export const validations = ...
export default {
  data() {
    validations,
    // ...
  }
}
</script>


describe('NewsForm', () => {
let wrapper;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could have merged whitespace changes to keep the PR diff small.

expect(paragraph.text()).toEqual("The list is empty :(");
wrapper.destroy();
expect(paragraph.text()).toEqual("The list is empty :(");
testWrapper.destroy();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it necessary to call testWrapper.destroy()?

}, shallowMount)
await testWrapper.vm.addItem('Title_3');
expect(writeMutateMock).toBeCalled()
expect(queryMock).toHaveBeenCalledTimes(2); // After writing, we also expect vue to rerender the component and therefore query the news again
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this is not necessary. Once the write mutation completes, it adds the new post to the cached posts query, thus triggering a re-render without unnecessary graphql queries.

@medizinmensch
Copy link
Copy Markdown
Contributor

Hi Team!

Let's summarize first:

⭐ For instructions in the README.md on how to build your webapp for production.
⭐ For no changes in "Files Changed" tab of the refactoring from vue-cli to create-nuxt-app. (See #1 in instructions)
⭐ ⭐ For the API connection between your front- and backend.
⭐ For your previous frontend tests still passing. Requests to the backend are mocked.
⭐ ⭐ For a login feature in your webapp including a Vue component and its software tests.
⭐ ⭐ For a menu component which shows a login or logout button and its software tests.
⭐ For an upvote button that behaves according to the authentication state of your user
❌ For a delete and edit button that is only visible to the author of the post.
⭐ For Lighthouse reporting that your production website is installable as PWA (except HTTPS).
⭐ For requesting a review and reviewing another team's PR.

As it was correctly pointed out by @aloparev, you did not implement an edit button. that is very unfortunate as it basically only one line missing. The exercise stated that you did not have to implement the functionality behind it (neither front- nor backend!).

But it's still 12/13 ⭐ which is great!

Two more things:

  1. I like your Readme! 👌
  2. You get many many warnings in your tests. If this was an actual job, I would have let you fix that first 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants