Browse Source

Merge branch 'query_node_active_video_counters_giza_staging' into olympia-update-tests

Leszek Wiesner 3 years ago
parent
commit
aba1030739

+ 2 - 9
tests/network-tests/run-full-tests.sh

@@ -42,15 +42,8 @@ yarn workspace api-scripts tsnode-strict src/status.ts | grep Runtime
 # Start a query-node
 ../../query-node/start.sh
 
-# Setup storage & distribution
-HOST_IP=$(./get-host-ip.sh)
-export COLOSSUS_1_URL="http://${HOST_IP}:3333"
-export DISTRIBUTOR_1_URL="http://${HOST_IP}:3334"
-./run-test-scenario.sh initStorageAndDistribution
-
-# Start colossus & argus
-docker-compose -f ../../docker-compose.yml up -d colossus-1
-docker-compose -f ../../docker-compose.yml up -d distributor-1
+# Start storage and distribution services
+REUSE_KEYS=true ./start-storage.sh
 
 # Run full tests reusing the existing keys
 REUSE_KEYS=true IGNORE_HIRED_LEADS=true ./run-test-scenario.sh $SCENARIO

+ 13 - 4
tests/network-tests/run-tests.sh

@@ -22,16 +22,25 @@ yarn workspace api-scripts tsnode-strict src/status.ts | grep Runtime
 # docker-compose -f ../../docker-compose.yml up -d colossus-1
 
 # Start a query-node
-../../query-node/start.sh
+if [ "${NO_QN}" != true ]
+then
+  ../../query-node/start.sh
+fi
 
 # Execute tests
 
 # We can load env config used to start docker services and pass them on to the
 # tests. This could be useful to capture keys used or URLs.
 # We just have to watchout for clashing env var names.
-#set -a
-#. ../../.env
-#set +a
+set -a
+. ../../.env
+set +a
+
+if [ "${NO_STORAGE}" != true ]
+then
+  ./start-storage.sh
+  export REUSE_KEYS=true
+fi
 
 # First scenario..
 ./run-test-scenario.sh $1

+ 19 - 29
tests/network-tests/src/QueryNodeApi.ts

@@ -299,22 +299,18 @@ import {
   GetChannelByIdQuery,
   GetChannelByIdQueryVariables,
   ChannelFieldsFragment,
+  ChannelCategoryFieldsFragment,
+  GetChannelCategoryByIdQuery,
+  GetChannelCategoryByIdQueryVariables,
+  GetChannelCategoryById,
+  VideoCategoryFieldsFragment,
+  GetVideoCategoryByIdQuery,
+  GetVideoCategoryByIdQueryVariables,
+  GetVideoCategoryById,
   OwnedNftFieldsFragment,
   GetOwnedNftByVideoId,
   GetOwnedNftByVideoIdQuery,
   GetOwnedNftByVideoIdQueryVariables,
-  GetChannelsVideoCountersQuery,
-  ChannelVideoCounterFragment,
-  GetChannelsVideoCountersQueryVariables,
-  GetChannelsVideoCounters,
-  ChannelCategoryVideoCounterFragment,
-  GetChannelCategoriesVideoCounterQuery,
-  GetChannelCategoriesVideoCounterQueryVariables,
-  GetChannelCategoriesVideoCounter,
-  VideoCategoryVideoCounterFragment,
-  GetVideoCategoriesVideoCounterQuery,
-  GetVideoCategoriesVideoCounterQueryVariables,
-  GetVideoCategoriesVideoCounter,
 } from './graphql/generated/queries'
 import { Maybe } from './graphql/generated/schema'
 import { OperationDefinitionNode } from 'graphql'
@@ -1100,26 +1096,20 @@ export class QueryNodeApi {
     )
   }
 
-  public async getChannelsVideoCounters(): Promise<ChannelVideoCounterFragment[]> {
-    return this.multipleEntitiesQuery<GetChannelsVideoCountersQuery, GetChannelsVideoCountersQueryVariables>(
-      GetChannelsVideoCounters,
-      {},
-      'channels'
+  public async channelCategoryById(id: string): Promise<Maybe<ChannelCategoryFieldsFragment>> {
+    return this.uniqueEntityQuery<GetChannelCategoryByIdQuery, GetChannelCategoryByIdQueryVariables>(
+      GetChannelCategoryById,
+      { id },
+      'channelCategoryByUniqueInput'
     )
   }
 
-  public async getChannelCategoriesVideoCounters(): Promise<ChannelCategoryVideoCounterFragment[]> {
-    return this.multipleEntitiesQuery<
-      GetChannelCategoriesVideoCounterQuery,
-      GetChannelCategoriesVideoCounterQueryVariables
-    >(GetChannelCategoriesVideoCounter, {}, 'channelCategories')
-  }
-
-  public async getVideoCategoriesVideoCounters(): Promise<VideoCategoryVideoCounterFragment[]> {
-    return this.multipleEntitiesQuery<
-      GetVideoCategoriesVideoCounterQuery,
-      GetVideoCategoriesVideoCounterQueryVariables
-    >(GetVideoCategoriesVideoCounter, {}, 'videoCategories')
+  public async videoCategoryById(id: string): Promise<Maybe<VideoCategoryFieldsFragment>> {
+    return this.uniqueEntityQuery<GetVideoCategoryByIdQuery, GetVideoCategoryByIdQueryVariables>(
+      GetVideoCategoryById,
+      { id },
+      'videoCategoryByUniqueInput'
+    )
   }
 
   public async ownedNftByVideoId(videoId: string): Promise<Maybe<OwnedNftFieldsFragment>> {

+ 2 - 2
tests/network-tests/src/cli/base.ts

@@ -79,8 +79,8 @@ export abstract class CLI {
             ...execOutputs,
             exitCode: 0,
           }
-        } catch (error) {
-          const errorTyped = error as ExecFileException & { stdout: string; stderr: string }
+        } catch (error: unknown) {
+          const errorTyped = error as ExecFileException & { stdout?: string; stderr?: string }
           // escape if command's success is required
           if (requireSuccess) {
             throw error

+ 35 - 23
tests/network-tests/src/cli/joystream.ts

@@ -2,10 +2,19 @@ import { KeyringPair } from '@polkadot/keyring/types'
 import path from 'path'
 import { CLI, CommandResult } from './base'
 import { TmpFileManager } from './utils'
-import { MemberId } from '@joystream/types/common'
+import {
+  VideoInputParameters,
+  ChannelCreationInputParameters,
+  ChannelUpdateInputParameters,
+  ChannelCategoryInputParameters,
+  VideoCategoryInputParameters,
+} from '@joystream/cli/src/Types'
+import ExitCodes from '@joystream/cli/src/ExitCodes'
 
 const CLI_ROOT_PATH = path.resolve(__dirname, '../../../../cli')
 
+type Modify<T, R> = Omit<T, keyof R> & R
+
 export interface ICreatedVideoData {
   videoId: number
   assetContentIds: string[]
@@ -75,30 +84,26 @@ export class JoystreamCLI extends CLI {
     return parseInt((text.match(/with id (\d+) successfully created/) as RegExpMatchArray)[1])
   }
 
-  /**
-    Checks if CLI's stderr contains warning about no storage provider available.
+  /*
+    Decide if CLI error indicates that storage provider is not available.
   */
-  private containsWarningNoStorage(stderr: string): boolean {
-    return !!stderr.match(/^\s*\S\s*Warning: No storage provider is currently available!/m)
-  }
-
-  /**
-    Checks if CLI's stderr contains warning about no password used when importing account.
-  */
-  private containsWarningEmptyPassword(text: string): boolean {
-    return !!text.match(/^\s*\S\s*Warning: Using empty password is not recommended!/)
+  private isErrorDueToNoStorage(exitCode: number): boolean {
+    // TODO: remove `% 256` after https://github.com/Joystream/joystream/issues/3251 is fixed
+    return exitCode === ExitCodes.ActionCurrentlyUnavailable % 256
   }
 
   /**
     Creates a new channel.
   */
-  async createChannel(channel: unknown, args: string[]): Promise<number> {
+  async createChannel(
+    channel: Modify<ChannelCreationInputParameters, { category?: number }>,
+    args: string[]
+  ): Promise<number> {
     const jsonFile = this.tmpFileManager.jsonFile(channel)
 
     const { out, stderr, exitCode } = await this.run('content:createChannel', ['--input', jsonFile, ...args])
 
-    if (exitCode && !this.containsWarningNoStorage(stderr)) {
-      // ignore warnings
+    if (exitCode && !this.isErrorDueToNoStorage(exitCode)) {
       throw new Error(`Unexpected CLI failure on creating channel: "${stderr}"`)
     }
 
@@ -108,7 +113,7 @@ export class JoystreamCLI extends CLI {
   /**
     Creates a new channel category.
   */
-  async createChannelCategory(channelCategory: unknown): Promise<number> {
+  async createChannelCategory(channelCategory: ChannelCategoryInputParameters): Promise<number> {
     const jsonFile = this.tmpFileManager.jsonFile(channelCategory)
 
     const { stdout, stderr, exitCode } = await this.run('content:createChannelCategory', [
@@ -128,7 +133,11 @@ export class JoystreamCLI extends CLI {
   /**
     Creates a new video.
   */
-  async createVideo(channelId: number, video: unknown, canOmitUpload = true): Promise<ICreatedVideoData> {
+  async createVideo(
+    channelId: number,
+    video: Modify<VideoInputParameters, { category: number }>,
+    canOmitUpload = true
+  ): Promise<ICreatedVideoData> {
     const jsonFile = this.tmpFileManager.jsonFile(video)
 
     const { stdout, stderr, exitCode } = await this.run(
@@ -139,7 +148,7 @@ export class JoystreamCLI extends CLI {
     )
 
     // prevent error from CLI that create
-    if (canOmitUpload && exitCode && !this.containsWarningNoStorage(stderr)) {
+    if (canOmitUpload && exitCode && !this.isErrorDueToNoStorage(exitCode)) {
       // ignore warnings
       throw new Error(`Unexpected CLI failure on creating video: "${stderr}"`)
     }
@@ -156,7 +165,7 @@ export class JoystreamCLI extends CLI {
   /**
     Creates a new video category.
   */
-  async createVideoCategory(videoCategory: unknown): Promise<number> {
+  async createVideoCategory(videoCategory: VideoCategoryInputParameters): Promise<number> {
     const jsonFile = this.tmpFileManager.jsonFile(videoCategory)
 
     const { stdout, stderr, exitCode } = await this.run('content:createVideoCategory', [
@@ -176,7 +185,7 @@ export class JoystreamCLI extends CLI {
   /**
     Updates an existing video.
   */
-  async updateVideo(videoId: number, video: unknown): Promise<void> {
+  async updateVideo(videoId: number, video: Modify<VideoInputParameters, { category: number }>): Promise<void> {
     const jsonFile = this.tmpFileManager.jsonFile(video)
 
     const { stdout, stderr, exitCode } = await this.run('content:updateVideo', [
@@ -185,7 +194,7 @@ export class JoystreamCLI extends CLI {
       videoId.toString(),
     ])
 
-    if (exitCode && !this.containsWarningNoStorage(stderr)) {
+    if (exitCode && !this.isErrorDueToNoStorage(exitCode)) {
       // ignore warnings
       throw new Error(`Unexpected CLI failure on creating video category: "${stderr}"`)
     }
@@ -194,7 +203,10 @@ export class JoystreamCLI extends CLI {
   /**
     Updates a channel.
   */
-  async updateChannel(channelId: number, channel: unknown): Promise<void> {
+  async updateChannel(
+    channelId: number,
+    channel: Modify<ChannelUpdateInputParameters, { category: number }>
+  ): Promise<void> {
     const jsonFile = this.tmpFileManager.jsonFile(channel)
 
     const { stdout, stderr, exitCode } = await this.run('content:updateChannel', [
@@ -203,7 +215,7 @@ export class JoystreamCLI extends CLI {
       channelId.toString(),
     ])
 
-    if (exitCode && !this.containsWarningNoStorage(stderr)) {
+    if (exitCode && !this.isErrorDueToNoStorage(exitCode)) {
       // ignore warnings
       throw new Error(`Unexpected CLI failure on creating video category: "${stderr}"`)
     }

+ 18 - 37
tests/network-tests/src/fixtures/content/activeVideoCounters.ts

@@ -1,23 +1,9 @@
 import { assert } from 'chai'
-import { ApolloQueryResult } from '@apollo/client'
 import { Api } from '../../Api'
-import { BaseQueryNodeFixture, FixtureRunner } from '../../Fixture'
-import { BuyMembershipHappyCaseFixture } from '../membership'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { Bytes } from '@polkadot/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
 import { QueryNodeApi } from '../../QueryNodeApi'
-import BN from 'bn.js'
-import { Worker, WorkerId } from '@joystream/types/working-group'
-
-import {
-  getMemberDefaults,
-  getChannelCategoryDefaults,
-  getChannelDefaults,
-  getVideoDefaults,
-  getVideoCategoryDefaults,
-} from './contentTemplates'
+import { Utils } from '../../utils'
 import { JoystreamCLI, ICreatedVideoData } from '../../cli/joystream'
-import * as path from 'path'
 
 /**
   Fixture that test Joystream content can be created, is reflected in query node,
@@ -55,20 +41,20 @@ export class ActiveVideoCountersFixture extends BaseQueryNodeFixture {
   */
   public async execute(): Promise<void> {
     const videoCount = this.videosData.length
-    const videoCategoryCount = this.videoCategoryIds.length
-    const channelCount = this.channelIds.length
-    const channelCategoryCount = this.channelCategoryIds.length
+    // const videoCategoryCount = this.videoCategoryIds.length
+    // const channelCount = this.channelIds.length
+    // const channelCategoryCount = this.channelCategoryIds.length
 
     // check channel and categories con are counted as active
 
     this.debug('Checking channels active video counters')
-    await this.assertCounterMatch('channels', this.channelIds[0], videoCount)
+    await this.assertCounterMatch('channel', this.channelIds[0], videoCount)
 
     this.debug('Checking channel categories active video counters')
-    await this.assertCounterMatch('channelCategories', this.channelCategoryIds[0], videoCount)
+    await this.assertCounterMatch('channelCategory', this.channelCategoryIds[0], videoCount)
 
     this.debug('Checking video categories active video counters')
-    await this.assertCounterMatch('videoCategories', this.videoCategoryIds[0], videoCount)
+    await this.assertCounterMatch('videoCategory', this.videoCategoryIds[0], videoCount)
 
     // move channel to different channel category and video to different videoCategory
 
@@ -86,10 +72,10 @@ export class ActiveVideoCountersFixture extends BaseQueryNodeFixture {
     // check counters of channel category and video category with newly moved in video/channel
 
     this.debug('Checking channel categories active video counters (2)')
-    await this.assertCounterMatch('channelCategories', this.channelCategoryIds[1], videoCount)
+    await this.assertCounterMatch('channelCategory', this.channelCategoryIds[1], videoCount)
 
     this.debug('Checking video categories active video counters (2)')
-    await this.assertCounterMatch('videoCategories', this.videoCategoryIds[1], oneMovedItemCount)
+    await this.assertCounterMatch('videoCategory', this.videoCategoryIds[1], oneMovedItemCount)
 
     /** Giza doesn't support changing channels - uncomment this on later releases where it's supported
 
@@ -103,8 +89,8 @@ export class ActiveVideoCountersFixture extends BaseQueryNodeFixture {
     // check counter of channel with newly moved video
 
     this.debug('Checking channels active video counters (2)')
-    await this.assertCounterMatch('channels', channelIds[0], videoCount - oneMovedItemCount)
-    await this.assertCounterMatch('channels', channelIds[1], oneMovedItemCount)
+    await this.assertCounterMatch('channel', channelIds[0], videoCount - oneMovedItemCount)
+    await this.assertCounterMatch('channel', channelIds[1], oneMovedItemCount)
 
     // end
     */
@@ -117,23 +103,18 @@ export class ActiveVideoCountersFixture extends BaseQueryNodeFixture {
     in Query node.
   */
   private async assertCounterMatch(
-    entityName: 'channels' | 'channelCategories' | 'videoCategories',
+    entityName: 'channel' | 'channelCategory' | 'videoCategory',
     entityId: number,
     expectedCount: number
   ) {
-    const getterName = `get${entityName[0].toUpperCase()}${entityName.slice(1)}VideoCounters` as
-      | 'getChannelsVideoCounters'
-      | 'getChannelCategoriesVideoCounters'
-      | 'getVideoCategoriesVideoCounters'
+    const getterName = `${entityName}ById` as 'channelById' | 'channelCategoryById' | 'videoCategoryById'
     await this.query.tryQueryWithTimeout(
-      () => this.query[getterName](),
-      (entities) => {
-        assert(entities.length > 0) // some entities were loaded
-
-        const entity = entities.find((item: any) => item.id === entityId.toString())
+      () => this.query[getterName](entityId.toString()),
+      (entity) => {
+        Utils.assert(entity)
 
         // all videos created in this fixture should be active and belong to first entity
-        assert(entity && entity.activeVideosCounter === expectedCount)
+        assert(entity.activeVideosCounter === expectedCount)
       }
     )
   }

+ 5 - 10
tests/network-tests/src/fixtures/content/contentTemplates.ts

@@ -1,9 +1,6 @@
 // basic templates for content entities
 
 import { v4 as uuid } from 'uuid'
-import * as path from 'path'
-
-export const cliExamplesFolderPath = path.dirname(require.resolve('@joystream/cli/package.json')) + '/examples/content'
 
 export function getMemberDefaults(index: number) {
   return {
@@ -12,9 +9,9 @@ export function getMemberDefaults(index: number) {
   }
 }
 
-export function getVideoDefaults(index: number) {
+export function getVideoDefaults(index: number, cliExamplesFolderPath: string) {
   return {
-    title: `Active video counters Testing channel - ${index} - ${uuid().substring(0, 8)}`,
+    title: 'Active video counters Testing channel',
     description: 'Video for testing active video counters.',
     videoPath: cliExamplesFolderPath + '/video.mp4',
     thumbnailPhotoPath: cliExamplesFolderPath + '/avatar-photo-1.png',
@@ -32,13 +29,13 @@ export function getVideoDefaults(index: number) {
 
 export function getVideoCategoryDefaults(index: number) {
   return {
-    name: `Active video counters Testing video category - ${index}`,
+    name: 'Active video counters Testing video category',
   }
 }
 
 export function getChannelDefaults(index: number, rewardAccountAddress: string) {
   return {
-    title: `Active video counters Testing channel - ${index}`,
+    title: 'Active video counters Testing channel',
     description: 'Channel for testing active video counters.',
     isPublic: true,
     language: 'en',
@@ -47,7 +44,5 @@ export function getChannelDefaults(index: number, rewardAccountAddress: string)
 }
 
 export function getChannelCategoryDefaults(index: number) {
-  return {
-    name: `Active video counters Testing channel category - ${index}`,
-  }
+  return {}
 }

+ 8 - 73
tests/network-tests/src/fixtures/content/createChannelsAndVideos.ts

@@ -1,17 +1,9 @@
-import { BaseQueryNodeFixture, FixtureRunner } from '../../Fixture'
+import { BaseQueryNodeFixture } from '../../Fixture'
 import { JoystreamCLI, ICreatedVideoData } from '../../cli/joystream'
-import { MemberId } from '@joystream/types/common'
 import { QueryNodeApi } from '../../QueryNodeApi'
 import { Api } from '../../Api'
 import * as path from 'path'
-import { getMemberDefaults, getVideoDefaults, getChannelDefaults } from './contentTemplates'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { BuyMembershipHappyCaseFixture } from '../membership'
-import BN from 'bn.js'
-import { DataObjectId, StorageBucketId } from '@joystream/types/storage'
-import { Worker, WorkerId } from '@joystream/types/working-group'
-import { createType } from '@joystream/types'
-import { singleBucketConfig } from '../../flows/storage/initStorage'
+import { getVideoDefaults, getChannelDefaults } from './contentTemplates'
 import { IMember } from './createMembers'
 
 const cliExamplesFolderPath = path.dirname(require.resolve('@joystream/cli/package.json')) + '/examples/content'
@@ -64,11 +56,7 @@ export class CreateChannelsAndVideosFixture extends BaseQueryNodeFixture {
     await this.cli.importAccount(this.author.keyringPair)
 
     this.debug('Creating channels')
-    this.createdItems.channelIds = await this.createChannels(
-      this.channelCount,
-      this.channelCategoryId,
-      this.author.account
-    )
+    this.createdItems.channelIds = await this.createChannels(this.channelCount, this.channelCategoryId)
 
     this.debug('Creating videos')
     this.createdItems.videosData = await this.createVideos(
@@ -76,74 +64,21 @@ export class CreateChannelsAndVideosFixture extends BaseQueryNodeFixture {
       this.createdItems.channelIds[0],
       this.videoCategoryId
     )
-
-    const { storageBucketId, storageGroupWorkerId, storageGroupWorkerAccount } = await this.retrieveBucket()
-
-    // TODO: remove this after "not enough balance" is solved for this worker
-    this.debug('Top-uping worker')
-    await this.api.treasuryTransferBalanceToAccounts([storageGroupWorkerAccount], new BN(1_000_000))
-
-    this.debug('Accepting content to storage bag')
-    const allAssetIds = this.createdItems.videosData.map((item) => item.assetContentIds).flat()
-    await this.api.acceptPendingDataObjects(
-      storageGroupWorkerAccount,
-      storageGroupWorkerId,
-      storageBucketId,
-      this.createdItems.channelIds[0].toString(),
-      allAssetIds
-    )
-  }
-
-  /**
-    Retrieves storage bucket info.
-  */
-  private async retrieveBucket(): Promise<{
-    storageBucketId: StorageBucketId
-    storageGroupWorkerId: WorkerId
-    storageGroupWorkerAccount: string
-  }> {
-    // read existing storage buckets from runtime
-    const bucketEntries = await this.api.query.storage.storageBucketById.entries()
-
-    // create WorkerId object
-    const storageGroupWorkerId = createType('WorkerId', singleBucketConfig.buckets[0].operatorId)
-
-    // find some bucket created by worker
-    const bucketTuple = bucketEntries.find(
-      ([, /* storageBucketId */ storageBucket]) =>
-        (storageBucket.operator_status as any).isStorageWorker &&
-        (storageBucket.operator_status as any).asStorageWorker[0].toString() === storageGroupWorkerId.toString()
-    )
-    if (!bucketTuple) {
-      throw new Error('Storage bucket not initialized')
-    }
-
-    // retrieve worker address
-    const storageGroupWorkerAccount = this.api.getAddressFromSuri(singleBucketConfig.buckets[0].transactorUri)
-
-    // create StorageBucketId object
-    const storageBucketId = createType('StorageBucketId', bucketTuple[0].args[0])
-
-    return {
-      storageBucketId,
-      storageGroupWorkerId,
-      storageGroupWorkerAccount,
-    }
   }
 
   /**
     Creates a new channel.
   */
-  private async createChannels(count: number, channelCategoryId: number, authorAddress: string): Promise<number[]> {
-    const createdIds = (await this.createCommonEntities(count, (index) =>
+  private async createChannels(count: number, channelCategoryId: number): Promise<number[]> {
+    const createdIds = await this.createCommonEntities(count, (index) =>
       this.cli.createChannel(
         {
-          ...getChannelDefaults(index, authorAddress),
+          ...getChannelDefaults(index, this.author.account),
           category: channelCategoryId,
         },
         ['--context', 'Member', '--useMemberId', this.author.memberId.toString()]
       )
-    )) as number[]
+    )
 
     return createdIds
   }
@@ -156,7 +91,7 @@ export class CreateChannelsAndVideosFixture extends BaseQueryNodeFixture {
   private async createVideos(count: number, channelId: number, videoCategoryId: number): Promise<ICreatedVideoData[]> {
     const createVideo = async (index: number) => {
       return await this.cli.createVideo(channelId, {
-        ...getVideoDefaults(index),
+        ...getVideoDefaults(index, cliExamplesFolderPath),
         category: videoCategoryId,
       })
     }

+ 8 - 10
tests/network-tests/src/fixtures/content/createContentStructure.ts

@@ -1,12 +1,10 @@
-import { BaseQueryNodeFixture, FixtureRunner } from '../../Fixture'
+import { BaseQueryNodeFixture } from '../../Fixture'
 import { JoystreamCLI } from '../../cli/joystream'
 import { QueryNodeApi } from '../../QueryNodeApi'
-import { MemberId } from '@joystream/types/common'
 import { Api } from '../../Api'
-import { WorkingGroupModuleName } from '../../types'
-import { Worker, WorkerId } from '@joystream/types/working-group'
+import { Worker } from '@joystream/types/working-group'
 import { getVideoCategoryDefaults, getChannelCategoryDefaults } from './contentTemplates'
-import BN from 'bn.js'
+import { WorkingGroupModuleName } from '../../types'
 
 export class CreateContentStructureFixture extends BaseQueryNodeFixture {
   private cli: JoystreamCLI
@@ -83,11 +81,11 @@ export class CreateContentStructureFixture extends BaseQueryNodeFixture {
     Creates a new channel category. Can only be executed as content group leader.
   */
   private async createChannelCategories(count: number): Promise<number[]> {
-    const createdIds = (await this.createCommonEntities(count, (index: number) =>
+    const createdIds = await this.createCommonEntities(count, (index) =>
       this.cli.createChannelCategory({
         ...getChannelCategoryDefaults(index),
       })
-    )) as number[]
+    )
 
     return createdIds
   }
@@ -96,11 +94,11 @@ export class CreateContentStructureFixture extends BaseQueryNodeFixture {
     Creates a new video category. Can only be executed as content group leader.
   */
   private async createVideoCategories(count: number): Promise<number[]> {
-    const createdIds = (await this.createCommonEntities(count, (index: number) =>
+    const createdIds = await this.createCommonEntities(count, (index) =>
       this.cli.createVideoCategory({
         ...getVideoCategoryDefaults(index),
       })
-    )) as number[]
+    )
 
     return createdIds
   }
@@ -109,7 +107,7 @@ export class CreateContentStructureFixture extends BaseQueryNodeFixture {
     Creates a bunch of content entities.
   */
   private async createCommonEntities<T>(count: number, createPromise: (index: number) => Promise<T>): Promise<T[]> {
-    const createdIds = await Array.from(Array(count).keys()).reduce(async (accPromise, index) => {
+    const createdIds = await Array.from(Array(count).keys()).reduce(async (accPromise, index: number) => {
       const acc = await accPromise
       const createdId = await createPromise(index)
 

+ 32 - 44
tests/network-tests/src/graphql/generated/queries.ts

@@ -47,6 +47,8 @@ export type StorageDataObjectFieldsFragment = {
 }
 
 export type ChannelFieldsFragment = {
+  id: string
+  activeVideosCounter: number
   title?: Types.Maybe<string>
   description?: Types.Maybe<string>
   isPublic?: Types.Maybe<boolean>
@@ -60,17 +62,9 @@ export type ChannelFieldsFragment = {
   coverPhoto?: Types.Maybe<StorageDataObjectFieldsFragment>
 }
 
-export type ChannelVideoCounterFragment = { id: string; activeVideosCounter: number }
-
-export type ChannelCategoryVideoCounterFragment = { id: string; activeVideosCounter: number }
+export type ChannelCategoryFieldsFragment = { id: string; activeVideosCounter: number }
 
-export type VideoCategoryVideoCounterFragment = { id: string; activeVideosCounter: number }
-
-export type GetChannelByIdQueryVariables = Types.Exact<{
-  id: Types.Scalars['ID']
-}>
-
-export type GetChannelByIdQuery = { channelByUniqueInput?: Types.Maybe<ChannelFieldsFragment> }
+export type VideoCategoryFieldsFragment = { id: string; activeVideosCounter: number }
 
 export type OwnedNftFieldsFragment = {
   id: string
@@ -85,17 +79,23 @@ export type OwnedNftFieldsFragment = {
     | { __typename: 'TransactionalStatusBuyNow' }
 }
 
-export type GetChannelsVideoCountersQueryVariables = Types.Exact<{ [key: string]: never }>
+export type GetChannelByIdQueryVariables = Types.Exact<{
+  id: Types.Scalars['ID']
+}>
 
-export type GetChannelsVideoCountersQuery = { channels: Array<ChannelVideoCounterFragment> }
+export type GetChannelByIdQuery = { channelByUniqueInput?: Types.Maybe<ChannelFieldsFragment> }
 
-export type GetChannelCategoriesVideoCounterQueryVariables = Types.Exact<{ [key: string]: never }>
+export type GetChannelCategoryByIdQueryVariables = Types.Exact<{
+  id: Types.Scalars['ID']
+}>
 
-export type GetChannelCategoriesVideoCounterQuery = { channelCategories: Array<ChannelCategoryVideoCounterFragment> }
+export type GetChannelCategoryByIdQuery = { channelCategoryByUniqueInput?: Types.Maybe<ChannelCategoryFieldsFragment> }
 
-export type GetVideoCategoriesVideoCounterQueryVariables = Types.Exact<{ [key: string]: never }>
+export type GetVideoCategoryByIdQueryVariables = Types.Exact<{
+  id: Types.Scalars['ID']
+}>
 
-export type GetVideoCategoriesVideoCounterQuery = { videoCategories: Array<VideoCategoryVideoCounterFragment> }
+export type GetVideoCategoryByIdQuery = { videoCategoryByUniqueInput?: Types.Maybe<VideoCategoryFieldsFragment> }
 
 export type GetOwnedNftByVideoIdQueryVariables = Types.Exact<{
   videoId: Types.Scalars['ID']
@@ -2044,6 +2044,8 @@ export const StorageDataObjectFields = gql`
 `
 export const ChannelFields = gql`
   fragment ChannelFields on Channel {
+    id
+    activeVideosCounter
     title
     description
     isPublic
@@ -2070,20 +2072,14 @@ export const ChannelFields = gql`
   }
   ${StorageDataObjectFields}
 `
-export const ChannelVideoCounter = gql`
-  fragment ChannelVideoCounter on Channel {
-    id
-    activeVideosCounter
-  }
-`
-export const ChannelCategoryVideoCounter = gql`
-  fragment ChannelCategoryVideoCounter on ChannelCategory {
+export const ChannelCategoryFields = gql`
+  fragment ChannelCategoryFields on ChannelCategory {
     id
     activeVideosCounter
   }
 `
-export const VideoCategoryVideoCounter = gql`
-  fragment VideoCategoryVideoCounter on VideoCategory {
+export const VideoCategoryFields = gql`
+  fragment VideoCategoryFields on VideoCategory {
     id
     activeVideosCounter
   }
@@ -3869,29 +3865,21 @@ export const GetChannelById = gql`
   }
   ${ChannelFields}
 `
-export const GetChannelsVideoCounters = gql`
-  query getChannelsVideoCounters {
-    channels {
-      ...ChannelVideoCounter
-    }
-  }
-  ${ChannelVideoCounter}
-`
-export const GetChannelCategoriesVideoCounter = gql`
-  query getChannelCategoriesVideoCounter {
-    channelCategories {
-      ...ChannelCategoryVideoCounter
+export const GetChannelCategoryById = gql`
+  query getChannelCategoryById($id: ID!) {
+    channelCategoryByUniqueInput(where: { id: $id }) {
+      ...ChannelCategoryFields
     }
   }
-  ${ChannelCategoryVideoCounter}
+  ${ChannelCategoryFields}
 `
-export const GetVideoCategoriesVideoCounter = gql`
-  query getVideoCategoriesVideoCounter {
-    videoCategories {
-      ...VideoCategoryVideoCounter
+export const GetVideoCategoryById = gql`
+  query getVideoCategoryById($id: ID!) {
+    videoCategoryByUniqueInput(where: { id: $id }) {
+      ...VideoCategoryFields
     }
   }
-  ${VideoCategoryVideoCounter}
+  ${VideoCategoryFields}
 `
 export const GetOwnedNftByVideoId = gql`
   query getOwnedNftByVideoId($videoId: ID!) {

+ 10 - 19
tests/network-tests/src/graphql/queries/content.graphql

@@ -36,6 +36,8 @@ fragment StorageDataObjectFields on StorageDataObject {
 }
 
 fragment ChannelFields on Channel {
+  id
+  activeVideosCounter
   title
   description
   isPublic
@@ -61,17 +63,12 @@ fragment ChannelFields on Channel {
   }
 }
 
-fragment ChannelVideoCounter on Channel {
+fragment ChannelCategoryFields on ChannelCategory {
   id
   activeVideosCounter
 }
 
-fragment ChannelCategoryVideoCounter on ChannelCategory {
-  id
-  activeVideosCounter
-}
-
-fragment VideoCategoryVideoCounter on VideoCategory {
+fragment VideoCategoryFields on VideoCategory {
   id
   activeVideosCounter
 }
@@ -97,21 +94,15 @@ query getChannelById($id: ID!) {
   }
 }
 
-query getChannelsVideoCounters {
-  channels {
-    ...ChannelVideoCounter
-  }
-}
-
-query getChannelCategoriesVideoCounter {
-  channelCategories {
-    ...ChannelCategoryVideoCounter
+query getChannelCategoryById($id: ID!) {
+  channelCategoryByUniqueInput(where: { id: $id }) {
+    ...ChannelCategoryFields
   }
 }
 
-query getVideoCategoriesVideoCounter {
-  videoCategories {
-    ...VideoCategoryVideoCounter
+query getVideoCategoryById($id: ID!) {
+  videoCategoryByUniqueInput(where: { id: $id }) {
+    ...VideoCategoryFields
   }
 }
 

+ 2 - 6
tests/network-tests/src/scenarios/content-directory.ts

@@ -1,14 +1,10 @@
 import leadOpening from '../flows/working-groups/leadOpening'
 import activeVideoCounters from '../flows/content/activeVideoCounters'
 import nftAuctionAndOffers from '../flows/content/nftAuctionAndOffers'
-import initStorage, { singleBucketConfig as storageConfig } from '../flows/storage/initStorage'
 import { scenario } from '../Scenario'
 
 scenario('Content directory', async ({ job }) => {
-  const leadSetupJob = job('Set WorkingGroup Leads', leadOpening())
-
-  const initStorageJob = job('initialize storage system', initStorage(storageConfig)).requires(leadSetupJob)
-
-  const videoCountersJob = job('check active video counters', activeVideoCounters).requires(initStorageJob)
+  const leadSetupJob = job('Set content working group leads', leadOpening(true, ['contentWorkingGroup']))
+  const videoCountersJob = job('check active video counters', activeVideoCounters).requires(leadSetupJob)
   job('nft auction and offers', nftAuctionAndOffers).after(videoCountersJob)
 })

+ 16 - 0
tests/network-tests/start-storage.sh

@@ -0,0 +1,16 @@
+TMP=$0
+THIS_DIR=`dirname $TMP`
+
+# make sure env variables are loaded before calling this script
+#set -a
+#. ../../.env
+#set +a
+
+HOST_IP=`$THIS_DIR/get-host-ip.sh`
+export COLOSSUS_1_URL="http://${HOST_IP}:3333"
+export DISTRIBUTOR_1_URL="http://${HOST_IP}:3334"
+$THIS_DIR/run-test-scenario.sh initStorageAndDistribution
+
+# Start colossus & argus
+docker-compose -f $THIS_DIR/../../docker-compose.yml up -d colossus-1
+docker-compose -f $THIS_DIR/../../docker-compose.yml up -d distributor-1

+ 1 - 0
types/augment/all/defs.json

@@ -816,5 +816,6 @@
         "non_channel_owner": "Option<MemberId>",
         "init_transactional_status": "InitTransactionalStatus"
     },
+    "NftMetadata": "Vec<u8>",
     "AccountInfo": "AccountInfoWithRefCount"
 }

+ 3 - 0
types/augment/all/types.ts

@@ -590,6 +590,9 @@ export interface NftIssuanceParameters extends Struct {
   readonly init_transactional_status: InitTransactionalStatus;
 }
 
+/** @name NftMetadata */
+export interface NftMetadata extends Bytes {}
+
 /** @name NftOwner */
 export interface NftOwner extends Enum {
   readonly isChannelOwner: boolean;

+ 3 - 3
yarn.lock

@@ -4714,9 +4714,9 @@ aws-credstash@^3.0.0:
     debug "^4.3.1"
 
 aws-sdk@^2.567.0:
-  version "2.1074.0"
-  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1074.0.tgz#be3283f781b3060cd67d5abef50d1edacefede70"
-  integrity sha512-tD478mkukglutjs+mq5FQmYFzz+l/wddl5u3tTMWTNa+j1eSL+AqaHPFM1rC3O9h98QqpKKzeKbLrPhGDvYaRg==
+  version "2.1078.0"
+  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1078.0.tgz#5871750b38045f05e141e5217521f8ff8bf73a26"
+  integrity sha512-eJuiiCE4tomYzsxqfsjERmQ1WQkNAe5RUhOXUwJbGTEfwmbiQqq/HgVYrwcMswOHoURbtKpB5SSrTLNOBuyurA==
   dependencies:
     buffer "4.9.2"
     events "1.1.1"