-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
upgrade apollo #2330
base: main
Are you sure you want to change the base?
upgrade apollo #2330
Conversation
Updates the versions in `package.json` so they install with no warnings about peer dependencies.
5c4a158
to
c61231e
Compare
!! OPEN ITEMS !! * Restore GraphQLError handling
@@ -1,10 +1,12 @@ | |||
import { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to my changing the imports VS code rearranged them.
@@ -1,5 +1,4 @@ | |||
import { log } from "../../../lib"; | |||
import { Assignment, r, cacheableData } from "../../models"; | |||
import { r, cacheableData } from "../../models"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted unused imports
@@ -363,7 +363,7 @@ it("should save campaign canned responses across copies and match saved data", a | |||
testAdminUser | |||
); | |||
expect(campaignDataResults.data.campaign.cannedResponses.length).toEqual(6); | |||
for (let i = 0; i < 6; i++) { | |||
for (let i = 0; i < 6; i += 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter complained about i++
so I changed it to i += 1
in several places
assignmentId | ||
}); | ||
|
||
const waitFor = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter complained about using await
inside a loop so I changed it to use this pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was a good call. Can you tell me how you decided that it should be an empty array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand the question?
The idea about the linter complaint and the change was to take await
out of the loop. We use an array to pass promises to Promise.all()
after the loop. We need to start with an empty array to add the promises to.
The whole thing probably could have been done differently, maybe something like the following (as someone did elsewhere in the file)
Promise.all(testContacts.slice(0,5).map(contact => sendMessage(contact.id, testTexterUser, {
userId: testTexterUser.id,
contactNumber: contact.cell,
text: "test text",
assignmentId: assignmentId.toString()
}))
* Changed arguments to `graphql` to match new signature and in some cases renamed variables to make it more convenient to use them in objects because of shorthand. * Apollo client 3 is stricter about typing so I added some type coersion in the tests * Cleaned some linter warnings about using `await` in loops and using the ++ operator refer to comments in the PR for callouts about some changes
396bd78
to
0ef104d
Compare
mySchema, | ||
operationText, | ||
const contextValue = getContext({ user }); | ||
const result = await graphql({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed arguments to match new signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the new signature in reference to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the graphql
function takes different parameters in the updated version compared to the older version
* Updated parameters for new signature of `graphql` * Coerced types for stricter graphql type checking * Cleaned up lints
throw new GraphQLError({ | ||
status: 401, | ||
message: "You must login to access that resource." | ||
throw new GraphQLError("You must login to access that resource.", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated for new signature.
@@ -166,12 +178,15 @@ describe("Message Hanlder: profanity-tagger", () => { | |||
expect(user).toBe(true); | |||
|
|||
// Confirm texter no-match | |||
await sendMessage(c.testContacts[1].id, c.testTexterUser, { | |||
userId: c.testTexterUser.id, | |||
await sendMessage(c.testContacts[1].id.toString(), c.testTexterUser, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious question @lperson
Should we change the data type within the test or within the code?
Or at least, could you help me understand why we would stringify the data result instead of ensuring that the data coming in from testContacts[1].id
is already a string?
That would ensure that the source is the correct data type, and instead we add an expect clause that confirms it is a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GREAT question!
I think we're ok here. In the client code we're getting all the values via graphql interfaces and they will come in as strings. In the tests we're taking integers from the database (the IDs) and passing them to graphql queries and mutations.
I don't think it's a good idea to change the type in the interface in order to avoid calling toString()
and parseInt()
in tests.
My reasoning when I made these changes was the UI code is internally consistent and the server code is internally consistent.
However I'm keeping an open mind in case my assumptions fall apart when I start banging on the UI (which is now).
@@ -16,12 +16,14 @@ export const GraphQLPhone = new GraphQLScalarType({ | |||
if (ast.kind !== Kind.STRING) { | |||
throw new GraphQLError( | |||
`Query error: Can only parse strings got a: ${ast.kind}`, | |||
[ast] | |||
{ nodes: [ast] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does nodes: [ast] do?
Is this a new dictionary process within graphql? With a data-type change this significant, I'm just curious how you knew this line needed to be updated. And how you knew this was the correct format?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A combination of https://www.apollographql.com/docs/apollo-server/data/errors/ and https://graphql-kr.github.io/graphql-js/error/
This code needs another pass though, which I'll do in a later commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nodes: [ast]
passes the abstract syntax tree for the graphql query into the error object. The particular code you highlighted looks at the ast
and decides if something passed as a phone number looks like a phone number and raises an exception if not. This is happening in the parseLiteral
hook which gives us a way to inspect and possibly alter a literal during parsing. GraphQLPhone
is a custom type in our code to handle phone numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! So I checked out the custom type hook you mentioned.
Confirming this is the correct file path: src/server/api/phone.js
The above file is imported to as GraphQLPhone inside our schema src/server/api/schema.js
and then exported within the constant resolvers
as a value for Phone.
I'm looking for the functionality where you say we could "possibly alter a literal." And now I see that the parseLiteral hook is being used on line 15 of the phone.js
file.
Would this functionality get in the way of seeing a toll-free number or a short-code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not know. This is not new functionality. It might be worth entering a ticket to test that and possibly fix it.
For contacts, it's unlikely we'll be using a toll-free number or short code to reach them. This code would be problematic if was used for the phone numbers we use to originate the texts, such as in the number purchasing code (as one example).
also some formatting from my editor
@@ -509,8 +511,8 @@ export class AssignmentTexterContactControls extends React.Component { | |||
|
|||
const otherResponsesLink = | |||
currentInteractionStep && | |||
currentInteractionStep.question.filteredAnswerOptions.length > 6 && | |||
filteredCannedResponses.length ? ( | |||
currentInteractionStep.question.filteredAnswerOptions.length > 6 && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From here down in this file all the changes are whitespace changes because my editor autoformatted the code.
@@ -125,7 +125,9 @@ export class AssignmentTexterContactControls extends React.Component { | |||
let currentInteractionStep = null; | |||
|
|||
if (availableSteps.length > 0) { | |||
currentInteractionStep = availableSteps[availableSteps.length - 1]; | |||
currentInteractionStep = structuredClone( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do a deep copy of data that originated in props
to avoid modifying props
@@ -13,8 +13,10 @@ export const isRoleGreater = (role1, role2) => | |||
export const hasRoleAtLeast = (hasRole, wantsRole) => | |||
ROLE_HIERARCHY.indexOf(hasRole) >= ROLE_HIERARCHY.indexOf(wantsRole); | |||
|
|||
export const getHighestRole = roles => | |||
roles.sort(isRoleGreater)[roles.length - 1]; | |||
export const getHighestRole = roles => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make a copy so we don't copy something that came from props
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you added tempRoles. Is this solely to remove an error message within development? Or is there a larger function here that's being updated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tempRoles
is is a variable to hold a deep copy of roles.
- Practical reason: with the updates, the code barfs when we try to modify a parameter of a react component. And by
barf
I mean it's a runtime error. - Best practice: don't modify your function's parameters!
@@ -1,4 +1,3 @@ | |||
import { GraphQLError } from "graphql/error"; | |||
import { getConfig } from "../../../server/api/lib/config"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like getConfig isn't being used in this file either. Should that be deleted also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, done! Good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are lots of places like this to clean up -- unused imports and other lints. I'm interested in doing that or maybe someone else could do it. I'm using vscode with integrated linting and I like to look at clean files (personal preference) but it's also a good practice to have zero lints.
I have tested this branch and haven't found any regressions |
Fixes #2329
Description
Upgrade apollo components. I needed to upgrade the server components as well because they coexist in
package.json
.Checklist: