Browse Source

fix image server references for tests (2 tests failing: missing function & looking for registration prompt for unregistered user)

Trent Larson 6 days ago
parent
commit
c9c3cacfbd
  1. 3
      .env.development
  2. 1
      .env.production
  3. 1
      .env.staging
  4. 27
      BUILDING.md
  5. 2
      playwright.config-local.ts
  6. 64
      src/App.vue
  7. 8
      src/components/PhotoDialog.vue
  8. 4
      src/main.ts
  9. 16
      src/router/index.ts
  10. 60
      src/views/AccountViewView.vue
  11. 5
      src/views/DiscoverView.vue
  12. 8
      src/views/GiftedDetailsView.vue
  13. 8
      src/views/NewEditProjectView.vue
  14. 8
      src/views/SharedPhotoView.vue
  15. 8
      test-playwright/35-record-gift-from-image-share.spec.ts
  16. 2
      test-playwright/40-add-contact.spec.ts
  17. 6
      vite.config.mjs

3
.env.development

@ -6,6 +6,7 @@ VITE_APP_SERVER=http://localhost:3000
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
VITE_DEFAULT_IMAGE_API_SERVER=http://localhost:3000
# Using shared server by default to ease setup, which works for shared test users.
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000
VITE_PASSKEYS_ENABLED=true

1
.env.production

@ -6,5 +6,6 @@ VITE_APP_SERVER=https://timesafari.app
# This is the claim ID for actions in the BVC project.
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01GXYPFF7FA03NXKPYY142PY4H
VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch

1
.env.staging

@ -6,6 +6,7 @@ VITE_APP_SERVER=https://test.timesafari.app
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch
VITE_PASSKEYS_ENABLED=true

27
BUILDING.md

@ -246,32 +246,7 @@ npm run lint-fix
## Environment Configuration
### Development
Create a `.env.development` file:
```bash
TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
VITE_APP_SERVER=http://localhost:3000
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
VITE_DEFAULT_IMAGE_API_SERVER=http://localhost:3000
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000
VITE_PASSKEYS_ENABLED=true
```
### Test/Staging
Create a `.env.staging` file:
```bash
TIME_SAFARI_APP_TITLE="TimeSafari_Test"
VITE_APP_SERVER=https://test.timesafari.app
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch
VITE_PASSKEYS_ENABLED=true
```
### Production
The `.env.production` file will be used automatically for production builds.
See `.env.*` files for configuration.
## Notes

2
playwright.config-local.ts

@ -119,7 +119,7 @@ export default defineConfig({
*/
webServer: {
command:
"VITE_APP_SERVER=http://localhost:8081 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_PASSKEYS_ENABLED=true npm run dev -- --port=8081",
"VITE_APP_SERVER=http://localhost:8081 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000 VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run dev -- --port=8081",
url: "http://localhost:8081",
reuseExistingServer: !process.env.CI,
},

64
src/App.vue

@ -333,46 +333,46 @@ export default class App extends Vue {
stopAsking = false;
created() {
console.log(
"Component created: Reactivity set up.",
window.location.pathname,
);
}
// created() {
// console.log(
// "Component created: Reactivity set up.",
// window.location.pathname,
// );
// }
truncateLongWords(sentence: string) {
return sentence
.split(" ")
.map((word) => (word.length > 30 ? word.slice(0, 30) + "..." : word))
.join(" ");
}
// beforeCreate() {
// console.log("Component beforeCreate: Instance initialized.");
// }
beforeCreate() {
console.log("Component beforeCreate: Instance initialized.");
}
// beforeMount() {
// console.log("Component beforeMount: Template is about to be rendered.");
// }
beforeMount() {
console.log("Component beforeMount: Template is about to be rendered.");
}
// mounted() {
// console.log("Component mounted: Template is now rendered.");
// }
mounted() {
console.log("Component mounted: Template is now rendered.");
}
// beforeUpdate() {
// console.log("Component beforeUpdate: DOM is about to be updated.");
// }
beforeUpdate() {
console.log("Component beforeUpdate: DOM is about to be updated.");
}
// updated() {
// console.log("Component updated: DOM has been updated.");
// }
updated() {
console.log("Component updated: DOM has been updated.");
}
// beforeUnmount() {
// console.log("Component beforeUnmount: Cleaning up before removal.");
// }
beforeUnmount() {
console.log("Component beforeUnmount: Cleaning up before removal.");
}
// unmounted() {
// console.log("Component unmounted: Component removed from the DOM.");
// }
unmounted() {
console.log("Component unmounted: Component removed from the DOM.");
truncateLongWords(sentence: string) {
return sentence
.split(" ")
.map((word) => (word.length > 30 ? word.slice(0, 30) + "..." : word))
.join(" ");
}
async turnOffNotifications(

8
src/components/PhotoDialog.vue

@ -369,6 +369,14 @@ export default class PhotoDialog extends Vue {
formData.append("image", this.blob, this.fileName || "snapshot.png");
formData.append("claimType", this.claimType);
try {
if (
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
const response = await axios.post(
DEFAULT_IMAGE_API_SERVER + "/image",
formData,

4
src/main.ts

@ -197,7 +197,7 @@ function setupGlobalErrorHandler(app: VueApp) {
);
};
}
console.log("Bootstrapping Vue app...");
// console.log("Bootstrapping Vue app...");
const app = createApp(App)
.component("fa", FontAwesomeIcon)
.component("camera", Camera)
@ -209,4 +209,4 @@ const app = createApp(App)
setupGlobalErrorHandler(app);
app.mount("#app");
console.log("Vue app mounted.");
// console.log("Vue app mounted.");

16
src/router/index.ts

@ -23,8 +23,6 @@ const enterOrStart = async (
const accountsDB = await accountsDBPromise;
const num_accounts = await accountsDB.accounts.count();
console.log("Number of accounts: ", num_accounts);
if (num_accounts > 0) {
next();
} else {
@ -299,8 +297,6 @@ const router = createRouter({
routes,
});
console.log("Initial URL:", initialPath);
// Replace initial URL to start at `/` if necessary
router.replace(initialPath || "/");
@ -319,12 +315,10 @@ const errorHandler = (
router.onError(errorHandler); // Assign the error handler to the router instance
router.beforeEach((to, from, next) => {
console.log("Navigating to view:", to.name);
console.log("From view:", from.name);
next();
});
console.log("Initial URL:", window.location.pathname);
// router.beforeEach((to, from, next) => {
// console.log("Navigating to view:", to.name);
// console.log("From view:", from.name);
// next();
// });
export default router;

60
src/views/AccountViewView.vue

@ -365,35 +365,41 @@
<div v-if="loadingLimits" class="text-center">
Checking&hellip; <fa icon="spinner" class="fa-spin"></fa>
</div>
<div>
<div class="mb-4 text-center">
{{ limitsMessage }}
</div>
<div v-if="!!endorserLimits?.nextWeekBeginDateTime">
<div>
<p class="text-sm">
You have done
<b>{{ endorserLimits.doneClaimsThisWeek }} claims</b> out of
<b>{{ endorserLimits.maxClaimsPerWeek }}</b> for this week. Your
claims counter resets at
<b>{{ endorserLimits?.doneClaimsThisWeek || "?" }} claims</b> out of
<b>{{ endorserLimits?.maxClaimsPerWeek || "?" }}</b> for this week.
Your claims counter resets at
<b class="whitespace-nowrap">{{
readableDate(endorserLimits.nextWeekBeginDateTime)
readableDate(endorserLimits?.nextWeekBeginDateTime)
}}</b>
</p>
<p class="mt-3 text-sm">
You have done
<b>{{ endorserLimits.doneRegistrationsThisMonth }} registrations</b>
out of <b>{{ endorserLimits.maxRegistrationsPerMonth }}</b> for this
month.
<i>(You cannot register anyone else on your first day.)</i>
<b
>{{
endorserLimits?.doneRegistrationsThisMonth || "?"
}}
registrations</b
>
out of
<b>{{ endorserLimits?.maxRegistrationsPerMonth || "?" }}</b> for this
this month.
<i>(You cannot register anyone on your first day.)</i>
Your registration counter resets at
<b class="whitespace-nowrap">
{{ readableDate(endorserLimits.nextMonthBeginDateTime) }}
{{ readableDate(endorserLimits?.nextMonthBeginDateTime) }}
</b>
</p>
<p class="mt-3 text-sm" v-if="!!imageLimits">
<p class="mt-3 text-sm">
You have uploaded
<b>{{ imageLimits?.doneImagesThisWeek }} images</b> out of
<b>{{ imageLimits?.maxImagesPerWeek }}</b> for this week. Your image
counter resets at
<b>{{ imageLimits?.doneImagesThisWeek || "?" }} images</b> out of
<b>{{ imageLimits?.maxImagesPerWeek || "?" }}</b> for this week. Your
image counter resets at
<b class="whitespace-nowrap">{{
readableDate(imageLimits?.nextWeekBeginDateTime)
}}</b>
@ -1215,7 +1221,7 @@ export default class AccountViewView extends Vue {
}
readableDate(timeStr: string) {
return timeStr.substring(0, timeStr.indexOf("T"));
return timeStr ? timeStr.substring(0, timeStr.indexOf("T")) : "?";
}
/**
@ -1230,11 +1236,11 @@ export default class AccountViewView extends Vue {
this.publicHex = identity.keys[0].publicKeyHex;
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
this.derivationPath = identity.keys[0].meta?.derivationPath as string;
await this.checkLimitsFor(this.activeDid);
await this.checkLimits();
} else if (account?.publicKeyHex) {
this.publicHex = account.publicKeyHex as string;
this.publicBase64 = Buffer.from(this.publicHex, "hex").toString("base64");
await this.checkLimitsFor(this.activeDid);
await this.checkLimits();
}
}
@ -1598,11 +1604,13 @@ export default class AccountViewView extends Vue {
}
/**
* Use "checkLimits" instead.
*
* Asynchronously checks rate limits for the given identity.
*
* Updates component state variables `limits`, `limitsMessage`, and `loadingLimits`.
*/
public async checkLimitsFor(did: string) {
private async checkLimitsFor(did: string) {
this.loadingLimits = true;
this.limitsMessage = "";
@ -1632,9 +1640,15 @@ export default class AccountViewView extends Vue {
);
}
}
try {
const imageResp = await fetchImageRateLimits(this.axios, did);
if (imageResp.status === 200) {
this.imageLimits = imageResp.data;
} else {
this.limitsMessage = "You don't have access to upload images.";
}
} catch {
this.limitsMessage = "You cannot upload images.";
}
}
} catch (error) {
@ -1739,6 +1753,14 @@ export default class AccountViewView extends Vue {
try {
const headers = await getHeaders(this.activeDid);
this.passkeyExpirationDescription = tokenExpiryTimeDescription();
if (
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
const response = await this.axios.delete(
DEFAULT_IMAGE_API_SERVER +
"/image/" +

5
src/views/DiscoverView.vue

@ -302,7 +302,10 @@ import InfiniteScroll from "../components/InfiniteScroll.vue";
import ProjectIcon from "../components/ProjectIcon.vue";
import OnboardingDialog from "../components/OnboardingDialog.vue";
import TopMessage from "../components/TopMessage.vue";
import { NotificationIface, DEFAULT_PARTNER_API_SERVER } from "../constants/app";
import {
NotificationIface,
DEFAULT_PARTNER_API_SERVER,
} from "../constants/app";
import {
db,
logConsoleAndDb,

8
src/views/GiftedDetailsView.vue

@ -547,6 +547,14 @@ export default class GiftedDetails extends Vue {
}
try {
const headers = await getHeaders(this.activeDid);
if (
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
const response = await this.axios.delete(
DEFAULT_IMAGE_API_SERVER +
"/image/" +

8
src/views/NewEditProjectView.vue

@ -357,6 +357,14 @@ export default class NewEditProjectView extends Vue {
}
try {
const headers = (await getHeaders(this.activeDid)) as AxiosRequestHeaders;
if (
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
const response = await this.axios.delete(
DEFAULT_IMAGE_API_SERVER +
"/image/" +

8
src/views/SharedPhotoView.vue

@ -183,6 +183,14 @@ export default class SharedPhotoView extends Vue {
);
formData.append("claimType", imageType);
if (
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
const response = await axios.post(
DEFAULT_IMAGE_API_SERVER + "/image",
formData,

8
test-playwright/35-record-gift-from-image-share.spec.ts

@ -50,6 +50,14 @@ import path from 'path';
import { test, expect } from '@playwright/test';
import { importUser } from './testUtils';
/**
* Note: by default, this test uses the test image API server.
*
* If you want to use your own image API server, you can set the
* VITE_DEFAULT_IMAGE_API_SERVER environment variable to your server's URL
* in the playwright.config-local.ts file.
*
*/
test('Record item given from image-share', async ({ page }) => {
let randomString = Math.random().toString(36).substring(2, 8);

2
test-playwright/40-add-contact.spec.ts

@ -300,7 +300,7 @@ test('Copy contact to clipboard, then import ', async ({ page, context }, testIn
return;
}
console.log("Running test that copies contact details to clipboard.");
// console.log("Running test that copies contact details to clipboard.");
await page.getByTestId('copySelectedContactsButtonTop').click();
const clipboardText = await page.evaluate(async () => {
return navigator.clipboard.readText();

6
vite.config.mjs

@ -33,12 +33,6 @@ export default defineConfig(({ mode }) => {
fs: {
strict: false
},
proxy: process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? {
'/api': {
target: process.env.VITE_DEFAULT_ENDORSER_API_SERVER || 'http://localhost:3000',
changeOrigin: true,
},
} : undefined,
},
build: {
outDir: isElectron ? "dist-electron" : "dist",

Loading…
Cancel
Save