Skip to content

Commit

Permalink
#66 templated view article (#112)
Browse files Browse the repository at this point in the history
* #66 initial article commit

* #66: Refactor article page, fetch article metadata

Moved Article.vue, separated out into article.js to match file structure
of other pages. Progressed on Semantic Scholar API logic.

* #66: Refactor article.js

* #66: Refactor Article.vue

* #66: Add route for Article View

Added route to explorer for the article view. Moved DOI from component
prop to a watcher and computed property pair.

* #66: Refactor article.js to move logic to services

Moved article metadata retrieval logic to services. Unified all metadata
under one object for simpler reference.

* #66: First pass at article HTML view

First attempt at displaying all article metadata. Also added pre-push
linting fixes.

* #66: Add loading state awareness

* #66: Add article venue to retrieved fields

* #66: Second pass at article view HTML

Added basic loading indicator, refactored table to have better structure
(I think)

* #66: Basic CSS for article view

* #66: Removed erroneous comment

* #66: Fix scrolling bug

Scrolling tables also scrolled their titles, but not their header rows.
Isolated tables in their own div, maybe tables should be their own
component...

* #66: Unify dir structure, nest article page

Move explorer/article/services to modules/explorer/article/services,
clean up article now that it's nested properly (barring further change
to nest completely under sample). Refactor extra function from fetchJSON
into getArticleMetadata.

* #66: initial Article.vue testing commit

Includes mock for Semantic Scholar API calls and article.js whitespace
linting fix.

* #66: Refactored getArticleMetadata for easier mock

Mocking getArticleMetadata easily required moving it into an enclosing
object so that the manual mock could do the same, allowing it to access
properties. The manual mock was written following along with
[jest's manual mock](https://jestjs.io/docs/manual-mocks).

The mock of the resulting getArticle also provides a stub of the
SemanticScholar API response as of 2/2/22, for reference and testing.

* #66: Write tests for Article.vue

Wrote tests of DOI loading, reloading; article data loading; API
failure. Added classes to article.html items to distinguish them and
allow the tests to refer to them. Updated article.js to use the new
articleMetadata.js and fixed bugs that appeared in testing.

* #66: Fix linting errors

* #66: Write tests for module articleMetadata.js

Updated articleMetadata mock to include raw and cleaned mock data, and
wrote tests of the fetch handler and response cleaning routines. Fixed
issues in articleMetadata.js that came up in testing.

* #66: Refactored articleMetadata.js to better track API errors

Refactored .get function to remove repeated code and allow API calls to
occur in parallel. Rewrote how internal fetch returns in order to pass
errors (and success codes) in API call along to caller. Updated mock
data to include mock version of success codes

* #66: Updated tests to match

Also added missing response codes to mock data, and fixed citation and
reference call status not being passed through

* #66: Updated Article.vue to display errors

Article view now takes advantage of newly passed API errors to inform
the user that an error has occurred. This could be expanded on

* #66: Linting fixes

* #66: Update test to use createWrapper

Replaced localVue, shallowMount with createWrapper for consistency.
Added test to ensure error message is displayed to user.

* #66: Write comments, refactor error storage

* #66: Write jsdoc-style function comments

Documented functions, removed unused mock response function, and
refactored testing slightly to remove repetition.

* #66: Move article to its own route

* #25: Remove console.logs, add reusable spinner
  • Loading branch information
roryschadler authored Feb 21, 2022
1 parent f94b710 commit ba64ce1
Show file tree
Hide file tree
Showing 9 changed files with 839 additions and 0 deletions.
90 changes: 90 additions & 0 deletions app/src/assets/css/modules/_misc.scss
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,93 @@
}
}
}

.article {
&_title {
margin: 1rem 0;
padding-bottom: 0.2rem;
}

&_subtitle {
margin: 1rem 0;
font-weight: bold;
font-size: 2.2rem;
}

&_authors {
margin: 1rem 0;
font-style: italic;
font-size: 2.2rem;
}

&_metadata {
margin: 1rem 0;
font-size: 1.5rem;

&_strong {
font-weight: bold;
}
}

&_abstract {
width: 90%;
font-size: 1.7rem;
line-height: 1.3;
margin: 1rem 0;
}

&_citations,&_references {
margin: 2rem 0;
}

&_table {
max-height: 50rem;
overflow: auto;

& > table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}

& tr {
border: solid;
border-color: #555;
border-width: 1px 0;

&:first-child {
border-top: none;
}

&:last-child {
border-bottom: none;
}
}

& th {
text-align: left;
font-size: 1.7rem;
position: sticky;
top: 0;
background: #eee;
&:nth-child(1){
width: 2.5em;
}
&:nth-child(2){
width: 20%;
}
&:nth-child(3){
width: 75%;
}
}

& td {
overflow: hidden;
max-width: 30%;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 1.5rem;
text-align: left;
}
}
}
251 changes: 251 additions & 0 deletions app/src/modules/explorer/article/services/__mocks__/articleMetadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/* globals jest */

// cleaned SemanticScholar API response, for comparison
export const cleanResponse = {
ok: true,
status: 200,
statusText: 'OK',
paperId: 'abc',
title: 'NanoMine schema: A shortened data representation for testing Article View',
abstract: 'Polymer nanocomposites consist of a polymer matrix and fillers like this is a testing matrix and filler material',
venue: 'APL Materials',
year: 2018,
citationCount: 2,
isOpenAccess: true,
authors: [
{
authorId: 'abc1',
name: 'He Zhao'
},
{
authorId: 'abc2',
name: 'Yixing Wang'
}
],
authorNames: 'He Zhao, Yixing Wang',
citations: [
{
ok: true,
status: 200,
statusText: 'OK',
paperId: 'def',
title: 'Bayesian Optimization for testing',
year: 2019,
authors: [
{
authorId: 'def1',
name: 'Yichi Zhang'
},
{
authorId: 'def2',
name: 'D. Apley'
}
],
authorNames: 'Yichi Zhang, D. Apley'
},
{
paperId: 'ghi',
title: 'Data-Centric Mixed-Variable Bayesian Optimization For Materials Design',
year: 2019,
authors: [
{
authorId: 'ghi1',
name: 'A. Iyer'
},
{
authorId: 'ghi2',
name: 'Yichi Zhang'
}
],
authorNames: 'A. Iyer, Yichi Zhang'
}
],
references: [
{
ok: true,
status: 200,
statusText: 'OK',
paperId: 'jkl',
title: 'A translation approach to portable ontology specifications',
year: 1993,
authors: [
{
authorId: 'jkl1',
name: 'T. Gruber'
}
],
authorNames: 'T. Gruber'
},
{
paperId: 'mno',
title: 'MatML: An XML for standardizing web-based materials property data',
year: 2000,
authors: [
{
authorId: 'mno1',
name: 'E. Begley'
},
{
authorId: 'mno2',
name: 'C. Sturrock'
}
],
authorNames: 'E. Begley, C. Sturrock'
}
]
}

// raw response from SemanticScholar API, split into article, references, and citations as
// returned from the REST API.
export const rawResponse = {
article: {
paperId: 'abc',
title: 'NanoMine schema: A shortened data representation for testing Article View',
abstract: 'Polymer nanocomposites consist of a polymer matrix and fillers like this is a testing matrix and filler material',
venue: 'APL Materials',
year: 2018,
citationCount: 2,
isOpenAccess: true,
authors: [
{
authorId: 'abc1',
name: 'He Zhao'
},
{
authorId: 'abc2',
name: 'Yixing Wang'
}
]
},
references: {
offset: 0,
data: [
{
citedPaper: {
paperId: 'jkl',
title: 'A translation approach to portable ontology specifications',
year: 1993,
authors: [
{
authorId: 'jkl1',
name: 'T. Gruber'
}
]
}
},
{
citedPaper: {
paperId: 'mno',
title: 'MatML: An XML for standardizing web-based materials property data',
year: 2000,
authors: [
{
authorId: 'mno1',
name: 'E. Begley'
},
{
authorId: 'mno2',
name: 'C. Sturrock'
}
]
}
},
{
citedPaper: {
paperId: null,
title: '',
year: 2011,
authors: []
}
},
{
citedPaper: {
paperId: null,
title: 'for Polymer Property Predictor and Database',
year: null,
authors: []
}
},
{
citedPaper: {
paperId: null,
title: '',
year: null,
authors: []
}
}
]
},
citations: {
offset: 0,
data: [
{
citingPaper: {
paperId: 'def',
title: 'Bayesian Optimization for testing',
year: 2019,
authors: [
{
authorId: 'def1',
name: 'Yichi Zhang'
},
{
authorId: 'def2',
name: 'D. Apley'
}
]
}
},
{
citingPaper: {
paperId: 'ghi',
title: 'Data-Centric Mixed-Variable Bayesian Optimization For Materials Design',
year: 2019,
authors: [
{
authorId: 'ghi1',
name: 'A. Iyer'
},
{
authorId: 'ghi2',
name: 'Yichi Zhang'
}
]
}
}
]
}
}

export default {
// control properties and their setters
testingData: true,
__setTestingData: function (value) {
this.testingData = !!value
},
testingRejection: false,
__setTestingRejection: function (value) {
this.testingRejection = !!value
},
__reset: function () {
this.testingData = true
this.testingRejection = false
},
/**
* A mock of @/components/modules/explorer/article/services/articleMetadata.get().
*
* Returns complete or empty data, or a rejected promise, depending on the desired
* testing scenario.
* @param {*} doi retained for compatibility with the original function
* @returns complete data, empty data, or a rejected Promise
*/
get: jest.fn(function ({ doi }) {
if (this.testingData) {
return Promise.resolve(cleanResponse)
} else if (this.testingRejection) {
return Promise.reject(new Error('Testing rejection of articleMetadata.get() Promise'))
} else {
return Promise.resolve()
}
})
}
Loading

0 comments on commit ba64ce1

Please sign in to comment.