Integration with Google Drive¶
Pytch can save (“export”) projects to, and load (“import”) projects from, Google Drive. This section summarises the design and implementation of this feature.
What’s stored¶
Export/import uses the same zipfile format as “download” / “upload”. When exporting, the filename is automatically generated along the lines of
My cool project (exported 20230516T160905).zip
API objects¶
Google Drive operations are provided through API objects, to allow Cypress-based testing of the UI flows under different error conditions.
The real Google API has a set-up phase where Google-provided scripts are loaded. There is therefore a boot process which returns an object capable of performing the Google Drive operations. (Or throws an exception if something goes wrong.)
Google Drive Boot API¶
Provides just the method boot()
, returning an object providing the
following API:
Google Drive API¶
Provides acquireToken()
, getUserInfo()
, importFiles()
and
exportFile()
methods. See docstrings in the code for details.
Authentication flow¶
There is an authentication and consent flow, mostly handled by
Google-provided code. Integration with the Pytch webapp is
complicated by the fact that we get a callback if the user gives or
refuses consent, but no callback if the user just closes the pop-up.
There is therefore a separate “Cancel” operation in the modal the app
shows while waiting for the Google pop-up to invoke one of our
callbacks. Communication regarding cancellation between the in-app
modal and the Google pop-up is handled by an AbortController
.
Google Cloud project¶
The system needs to be registered with Google, saying which API families are permitted, what sorts of user information it will want to access, and so on. This is set up manually through Google’s web console.
API keys and other identifiers: the .env
file¶
Various identifiers are needed when communicating with Google. These are stored in environment variables:
Client ID (env.var
VITE_GOOGLE_CLIENT_ID
)App ID (env.var
VITE_GOOGLE_APP_ID
)API key (env.var
VITE_GOOGLE_API_KEY
)
There is also an env.var indicating whether to use the real Google API, or a mock for testing — see below.
These are all stored in a .env
file which is not part of the repo.
Testing¶
There is a mock implementation of the two APIs. It can be configured to behave in certain ways so that Cypress can test the UI flow under different conditions.
Flows¶
There are two main flows: import and export. Each one needs the authentication flow to have been completed first.
Each flow is wrapped in doTask()
, with the following state
diagram:
Choice of real vs mock APIs¶
The real Google API objects are used for production builds and also for the development server when a particular React environment variable is set:
VITE_USE_REAL_GOOGLE_DRIVE=yes
Otherwise, the mock API objects are used, to allow Cypress testing. This does mean that you must stop and re-start the development server in order to switch between working with the real Google Drive and running tests.