diff --git a/backend/src/auth/INALIENABLE_RIGHTS.ts b/backend/src/auth/INALIENABLE_RIGHTS.ts index 348cd5b20..adca3640f 100644 --- a/backend/src/auth/INALIENABLE_RIGHTS.ts +++ b/backend/src/auth/INALIENABLE_RIGHTS.ts @@ -2,7 +2,6 @@ import { RIGHTS } from './RIGHTS' export const INALIENABLE_RIGHTS = [ RIGHTS.LOGIN, - RIGHTS.GET_COMMUNITY_INFO, RIGHTS.COMMUNITIES, RIGHTS.CREATE_USER, RIGHTS.SEND_RESET_PASSWORD_EMAIL, diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 22be48e40..7ee60dbe5 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -2,7 +2,6 @@ export enum RIGHTS { LOGIN = 'LOGIN', VERIFY_LOGIN = 'VERIFY_LOGIN', BALANCE = 'BALANCE', - GET_COMMUNITY_INFO = 'GET_COMMUNITY_INFO', COMMUNITIES = 'COMMUNITIES', LIST_GDT_ENTRIES = 'LIST_GDT_ENTRIES', EXIST_PID = 'EXIST_PID', diff --git a/backend/src/graphql/model/Community.ts b/backend/src/graphql/model/Community.ts index 0cd1926f5..ec91ad36f 100644 --- a/backend/src/graphql/model/Community.ts +++ b/backend/src/graphql/model/Community.ts @@ -1,33 +1,47 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { ObjectType, Field, Int } from 'type-graphql' +import { Community as DbCommunity } from '@entity/Community' @ObjectType() export class Community { - constructor(json?: any) { - if (json) { - this.id = Number(json.id) - this.name = json.name - this.url = json.url - this.description = json.description - this.registerUrl = json.registerUrl - } + constructor(dbCom: DbCommunity) { + this.id = dbCom.id + this.foreign = dbCom.foreign + this.publicKey = dbCom.publicKey.toString() + this.url = + (dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/') + + 'api/' + + dbCom.apiVersion + this.lastAnnouncedAt = dbCom.lastAnnouncedAt + this.verifiedAt = dbCom.verifiedAt + this.lastErrorAt = dbCom.lastErrorAt + this.createdAt = dbCom.createdAt + this.updatedAt = dbCom.updatedAt } @Field(() => Int) id: number + @Field(() => Boolean) + foreign: boolean + @Field(() => String) - name: string + publicKey: string @Field(() => String) url: string - @Field(() => String) - description: string + @Field(() => Date, { nullable: true }) + lastAnnouncedAt: Date | null - @Field(() => String) - registerUrl: string + @Field(() => Date, { nullable: true }) + verifiedAt: Date | null + + @Field(() => Date, { nullable: true }) + lastErrorAt: Date | null + + @Field(() => Date, { nullable: true }) + createdAt: Date | null + + @Field(() => Date, { nullable: true }) + updatedAt: Date | null } diff --git a/backend/src/graphql/resolver/CommunityResolver.test.ts b/backend/src/graphql/resolver/CommunityResolver.test.ts index 95f2ec5dd..1e8f6a00f 100644 --- a/backend/src/graphql/resolver/CommunityResolver.test.ts +++ b/backend/src/graphql/resolver/CommunityResolver.test.ts @@ -1,24 +1,25 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/unbound-method */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { createTestClient } from 'apollo-server-testing' -import createServer from '@/server/createServer' -import CONFIG from '@/config' - -jest.mock('@/config') +import { getCommunities } from '@/seeds/graphql/queries' +import { Community as DbCommunity } from '@entity/Community' +import { testEnvironment } from '@test/helpers' let query: any // to do: We need a setup for the tests that closes the connection let con: any +let testEnv: any beforeAll(async () => { - const server = await createServer({}) - con = server.con - query = createTestClient(server.apollo).query + testEnv = await testEnvironment() + query = testEnv.query + con = testEnv.con + await DbCommunity.clear() }) afterAll(async () => { @@ -26,74 +27,90 @@ afterAll(async () => { }) describe('CommunityResolver', () => { - const getCommunityInfoQuery = ` - query { - getCommunityInfo { - name - description - url - registerUrl - } - } - ` - - const communities = ` - query { - communities { - id - name - url - description - registerUrl - } - } - ` - - describe('getCommunityInfo', () => { - it('returns the default values', async () => { - await expect(query({ query: getCommunityInfoQuery })).resolves.toMatchObject({ - data: { - getCommunityInfo: { - name: 'Gradido Entwicklung', - description: 'Die lokale Entwicklungsumgebung von Gradido.', - url: 'http://localhost/', - registerUrl: 'http://localhost/register', + describe('getCommunities', () => { + let homeCom1: DbCommunity + let homeCom2: DbCommunity + let homeCom3: DbCommunity + let foreignCom1: DbCommunity + let foreignCom2: DbCommunity + let foreignCom3: DbCommunity + describe('with empty list', () => { + it('returns no community entry', async () => { + // const result: Community[] = await query({ query: getCommunities }) + // expect(result.length).toEqual(0) + await expect(query({ query: getCommunities })).resolves.toMatchObject({ + data: { + getCommunities: [], }, - }, + }) }) }) - }) - describe('communities', () => { - describe('PRODUCTION = false', () => { - beforeEach(() => { - CONFIG.PRODUCTION = false + describe('only home-communities entries', () => { + beforeEach(async () => { + jest.clearAllMocks() + + homeCom1 = DbCommunity.create() + homeCom1.foreign = false + homeCom1.publicKey = Buffer.from('publicKey-HomeCommunity') + homeCom1.apiVersion = '1_0' + homeCom1.endPoint = 'http://localhost' + homeCom1.createdAt = new Date() + await DbCommunity.insert(homeCom1) + + homeCom2 = DbCommunity.create() + homeCom2.foreign = false + homeCom2.publicKey = Buffer.from('publicKey-HomeCommunity') + homeCom2.apiVersion = '1_1' + homeCom2.endPoint = 'http://localhost' + homeCom2.createdAt = new Date() + await DbCommunity.insert(homeCom2) + + homeCom3 = DbCommunity.create() + homeCom3.foreign = false + homeCom3.publicKey = Buffer.from('publicKey-HomeCommunity') + homeCom3.apiVersion = '2_0' + homeCom3.endPoint = 'http://localhost' + homeCom3.createdAt = new Date() + await DbCommunity.insert(homeCom3) }) - it('returns three communities', async () => { - await expect(query({ query: communities })).resolves.toMatchObject({ + it('returns three home-community entries', async () => { + await expect(query({ query: getCommunities })).resolves.toMatchObject({ data: { - communities: [ + getCommunities: [ { id: 1, - name: 'Gradido Entwicklung', - description: 'Die lokale Entwicklungsumgebung von Gradido.', - url: 'http://localhost/', - registerUrl: 'http://localhost/register-community', + foreign: homeCom1.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/1_0'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom1.createdAt.toISOString(), + updatedAt: null, }, { id: 2, - name: 'Gradido Staging', - description: 'Der Testserver der Gradido-Akademie.', - url: 'https://stage1.gradido.net/', - registerUrl: 'https://stage1.gradido.net/register-community', + foreign: homeCom2.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/1_1'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom2.createdAt.toISOString(), + updatedAt: null, }, { id: 3, - name: 'Gradido-Akademie', - description: 'Freies Institut für Wirtschaftsbionik.', - url: 'https://gradido.net', - registerUrl: 'https://gdd1.gradido.com/register-community', + foreign: homeCom3.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/2_0'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom3.createdAt.toISOString(), + updatedAt: null, }, ], }, @@ -101,21 +118,104 @@ describe('CommunityResolver', () => { }) }) - describe('PRODUCTION = true', () => { - beforeEach(() => { - CONFIG.PRODUCTION = true + describe('plus foreign-communities entries', () => { + beforeEach(async () => { + jest.clearAllMocks() + + foreignCom1 = DbCommunity.create() + foreignCom1.foreign = true + foreignCom1.publicKey = Buffer.from('publicKey-ForeignCommunity') + foreignCom1.apiVersion = '1_0' + foreignCom1.endPoint = 'http://remotehost' + foreignCom1.createdAt = new Date() + await DbCommunity.insert(foreignCom1) + + foreignCom2 = DbCommunity.create() + foreignCom2.foreign = true + foreignCom2.publicKey = Buffer.from('publicKey-ForeignCommunity') + foreignCom2.apiVersion = '1_1' + foreignCom2.endPoint = 'http://remotehost' + foreignCom2.createdAt = new Date() + await DbCommunity.insert(foreignCom2) + + foreignCom3 = DbCommunity.create() + foreignCom3.foreign = true + foreignCom3.publicKey = Buffer.from('publicKey-ForeignCommunity') + foreignCom3.apiVersion = '1_2' + foreignCom3.endPoint = 'http://remotehost' + foreignCom3.createdAt = new Date() + await DbCommunity.insert(foreignCom3) }) - it('returns one community', async () => { - await expect(query({ query: communities })).resolves.toMatchObject({ + it('returns 3x home and 3x foreign-community entries', async () => { + await expect(query({ query: getCommunities })).resolves.toMatchObject({ data: { - communities: [ + getCommunities: [ + { + id: 1, + foreign: homeCom1.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/1_0'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom1.createdAt.toISOString(), + updatedAt: null, + }, + { + id: 2, + foreign: homeCom2.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/1_1'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom2.createdAt.toISOString(), + updatedAt: null, + }, { id: 3, - name: 'Gradido-Akademie', - description: 'Freies Institut für Wirtschaftsbionik.', - url: 'https://gradido.net', - registerUrl: 'https://gdd1.gradido.com/register-community', + foreign: homeCom3.foreign, + publicKey: expect.stringMatching('publicKey-HomeCommunity'), + url: expect.stringMatching('http://localhost/api/2_0'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: homeCom3.createdAt.toISOString(), + updatedAt: null, + }, + { + id: 4, + foreign: foreignCom1.foreign, + publicKey: expect.stringMatching('publicKey-ForeignCommunity'), + url: expect.stringMatching('http://remotehost/api/1_0'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: foreignCom1.createdAt.toISOString(), + updatedAt: null, + }, + { + id: 5, + foreign: foreignCom2.foreign, + publicKey: expect.stringMatching('publicKey-ForeignCommunity'), + url: expect.stringMatching('http://remotehost/api/1_1'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: foreignCom2.createdAt.toISOString(), + updatedAt: null, + }, + { + id: 6, + foreign: foreignCom3.foreign, + publicKey: expect.stringMatching('publicKey-ForeignCommunity'), + url: expect.stringMatching('http://remotehost/api/1_2'), + lastAnnouncedAt: null, + verifiedAt: null, + lastErrorAt: null, + createdAt: foreignCom3.createdAt.toISOString(), + updatedAt: null, }, ], }, diff --git a/backend/src/graphql/resolver/CommunityResolver.ts b/backend/src/graphql/resolver/CommunityResolver.ts index 4cd0c8f69..1292fa55f 100644 --- a/backend/src/graphql/resolver/CommunityResolver.ts +++ b/backend/src/graphql/resolver/CommunityResolver.ts @@ -1,58 +1,18 @@ import { Resolver, Query, Authorized } from 'type-graphql' import { Community } from '@model/Community' +import { Community as DbCommunity } from '@entity/Community' import { RIGHTS } from '@/auth/RIGHTS' -import CONFIG from '@/config' @Resolver() export class CommunityResolver { - @Authorized([RIGHTS.GET_COMMUNITY_INFO]) - @Query(() => Community) - getCommunityInfo(): Community { - return new Community({ - name: CONFIG.COMMUNITY_NAME, - description: CONFIG.COMMUNITY_DESCRIPTION, - url: CONFIG.COMMUNITY_URL, - registerUrl: CONFIG.COMMUNITY_REGISTER_URL, - }) - } - @Authorized([RIGHTS.COMMUNITIES]) @Query(() => [Community]) - communities(): Community[] { - if (CONFIG.PRODUCTION) - return [ - new Community({ - id: 3, - name: 'Gradido-Akademie', - description: 'Freies Institut für Wirtschaftsbionik.', - url: 'https://gradido.net', - registerUrl: 'https://gdd1.gradido.com/register-community', - }), - ] - return [ - new Community({ - id: 1, - name: 'Gradido Entwicklung', - description: 'Die lokale Entwicklungsumgebung von Gradido.', - url: 'http://localhost/', - registerUrl: 'http://localhost/register-community', - }), - new Community({ - id: 2, - name: 'Gradido Staging', - description: 'Der Testserver der Gradido-Akademie.', - url: 'https://stage1.gradido.net/', - registerUrl: 'https://stage1.gradido.net/register-community', - }), - new Community({ - id: 3, - name: 'Gradido-Akademie', - description: 'Freies Institut für Wirtschaftsbionik.', - url: 'https://gradido.net', - registerUrl: 'https://gdd1.gradido.com/register-community', - }), - ] + async getCommunities(): Promise { + const dbCommunities: DbCommunity[] = await DbCommunity.find({ + order: { foreign: 'ASC', publicKey: 'ASC', apiVersion: 'ASC' }, + }) + return dbCommunities.map((dbCom: DbCommunity) => new Community(dbCom)) } } diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 299a0103d..1d1cea823 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -133,6 +133,22 @@ export const communities = gql` } ` +export const getCommunities = gql` + query { + getCommunities { + id + foreign + publicKey + url + lastAnnouncedAt + verifiedAt + lastErrorAt + createdAt + updatedAt + } + } +` + export const queryTransactionLink = gql` query ($code: String!) { queryTransactionLink(code: $code) { diff --git a/database/entity/0060-update_communities_table/Community.ts b/database/entity/0060-update_communities_table/Community.ts index 5ded76cf9..ab7cfb58a 100644 --- a/database/entity/0060-update_communities_table/Community.ts +++ b/database/entity/0060-update_communities_table/Community.ts @@ -25,13 +25,13 @@ export class Community extends BaseEntity { endPoint: string @Column({ name: 'last_announced_at', type: 'datetime', nullable: true }) - lastAnnouncedAt: Date + lastAnnouncedAt: Date | null @Column({ name: 'verified_at', type: 'datetime', nullable: true }) - verifiedAt: Date + verifiedAt: Date | null @Column({ name: 'last_error_at', type: 'datetime', nullable: true }) - lastErrorAt: Date + lastErrorAt: Date | null @CreateDateColumn({ name: 'created_at',