Skip to content

Commit

Permalink
Merge pull request #125 from matter-labs/QA-573-rebase2-be-tests
Browse files Browse the repository at this point in the history
test: rebase2 be tests
  • Loading branch information
abilevych authored Dec 15, 2023
2 parents 7fe2e5a + ecea709 commit 7d93728
Show file tree
Hide file tree
Showing 123 changed files with 2,657 additions and 698 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/app-deploy-feature-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ jobs:

mainnet:
needs: build
name: Feature Env, Mainnet+
name: Feature on Mainnet + Sepolia
uses: ./.github/workflows/app-e2e.yml
secrets: inherit
permissions:
contents: read
with:
targetUrl: ${{ needs.build.outputs.dappUrl }}
testnet_network_value_for_e2e: "/?network=sepolia"
default_network_value_for_e2e: "/?network=mainnet"
publish_to_allure: true
environmentTags: "and not @productionEnv"
3 changes: 2 additions & 1 deletion .github/workflows/app-deploy-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ jobs:
mainnet:
needs: deploy
name: Staging Env, Mainnet+
name: Staging on Mainnet + Sepolia
uses: ./.github/workflows/app-e2e.yml
secrets: inherit
permissions:
contents: read
with:
targetUrl: ${{ needs.deploy.outputs.dappUrl }}
testnet_network_value_for_e2e: "/?network=sepolia"
default_network_value_for_e2e: "/?network=mainnet"
publish_to_allure: true
environmentTags: "and not @featureEnv"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/app-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ on:
type: string
default: '/?network=mainnet'
required: true
testnet_network_value_for_e2e:
type: string
default: '/?network=sepolia'
required: true
publish_to_allure: #Here we define the variable that can be overwritten by caller workflow
type: boolean
description: "Publish test results to allure"
Expand Down Expand Up @@ -69,7 +73,7 @@ jobs:
with:
node-version: '18'
cache: 'npm'

- name: Cache node modules
id: cache-nodemodules
uses: actions/cache@v3
Expand Down Expand Up @@ -106,7 +110,7 @@ jobs:
echo "Run tests"
if [ "${{ matrix.tags }}" = "@testnetSmokeSuite" ]; then
echo "Run in testnetSmokeSuite only"
E2ENETWORK='/?network=goerli' npx cucumber-js --tags "${{ matrix.tags }} ${{ inputs.environmentTags }} and not @mainnet"
E2ENETWORK='${{ inputs.testnet_network_value_for_e2e }}' npx cucumber-js --tags "${{ matrix.tags }} ${{ inputs.environmentTags }} and not @mainnet"
else
echo "Run in mainnet"
E2ENETWORK='${{ inputs.default_network_value_for_e2e }}' npx cucumber-js --tags "${{ matrix.tags }} ${{ inputs.environmentTags }} and not @testnet"
Expand Down
7 changes: 1 addition & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,7 @@ lerna-debug.log*
!.vscode/extensions.json

# Allure
#Allure results and artifacts
**/allure-results/
**/e2e/artifacts/
**/playbook/artifacts*
**/playbook/cache*
**/buffer/*.txt
**allure-results/

# App hyperchain config
hyperchain.config.json
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ flowchart
## 🛠 Installation

```bash
$ npm install
npm install
```

## ⚙️ Setting up env variables
Expand All @@ -65,7 +65,7 @@ Make sure you have [zksync-era](https://github.com/matter-labs/zksync-era) repo

The following script sets `.env` files for [Worker](./packages/worker) and [API](./packages/api) packages as well as environment configuration file for [App](./packages/app) package based on your local [zksync-era](https://github.com/matter-labs/zksync-era) repo setup.
```bash
$ npm run hyperchain:configure
npm run hyperchain:configure
```
You can review and edit generated files if you need to change any settings.

Expand All @@ -74,18 +74,18 @@ You can review and edit generated files if you need to change any settings.
Before running the solution, make sure you have a database server up and running, you have created a database and set up all the required environment variables.
To create a database run the following command:
```bash
$ npm run db:create
npm run db:create
```

To run all the packages (`Worker`, `API` and front-end `App`) in `development` mode run the following command from the root directory.
```bash
$ npm run dev
npm run dev
```

For `production` mode run:
```bash
$ npm run build
$ npm run start
npm run build
npm run start
```

Each component can also be started individually. Follow individual packages `README` for details.
Expand All @@ -107,15 +107,15 @@ To verify front-end `App` is running open http://localhost:3010 in your browser.
## 🕵️‍♂️ Testing
Run unit tests for all packages:
```bash
$ npm run test
npm run test
```
Run e2e tests for all packages:
```bash
$ npm run test:e2e
npm run test:e2e
```
Run tests for a specific package:
```bash
$ npm run test -w {package}
npm run test -w {package}
```
For more details on testing please check individual packages `README`.

Expand All @@ -131,7 +131,9 @@ zkSync Era Block Explorer is distributed under the terms of either
at your option.

## 🔗 Production links
- Testnet API: https://block-explorer-api.testnets.zksync.dev
- Testnet Goerli API: https://block-explorer-api.testnets.zksync.dev
- Testnet Sepolia API: https://block-explorer-api.sepolia.zksync.dev
- Mainnet API: https://block-explorer-api.mainnet.zksync.io
- Testnet App: https://goerli.explorer.zksync.io
- Testnet Goerli App: https://goerli.explorer.zksync.io
- Testnet Sepolia App: https://sepolia.explorer.zksync.io
- Mainnet App: https://explorer.zksync.io
21 changes: 2 additions & 19 deletions packages/api/src/address/address.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { BalanceService } from "../balance/balance.service";
import { BlockService } from "../block/block.service";
import { LogService } from "../log/log.service";
import { TransactionService } from "../transaction/transaction.service";
import { TransactionReceiptService } from "../transaction/transactionReceipt.service";
import { TransactionReceipt } from "../transaction/entities/transactionReceipt.entity";
import { Log } from "../log/log.entity";
import { Token } from "../token/token.entity";
import { PagingOptionsWithMaxItemsLimitDto } from "../common/dtos";
Expand All @@ -28,7 +26,6 @@ describe("AddressController", () => {
let logServiceMock: LogService;
let balanceServiceMock: BalanceService;
let transactionServiceMock: TransactionService;
let transactionReceiptServiceMock: TransactionReceiptService;
let transferServiceMock: TransferService;
const blockchainAddress = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
const normalizedAddress = "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF";
Expand All @@ -38,7 +35,6 @@ describe("AddressController", () => {
serviceMock = mock<AddressService>();
blockServiceMock = mock<BlockService>();
transactionServiceMock = mock<TransactionService>();
transactionReceiptServiceMock = mock<TransactionReceiptService>();
logServiceMock = mock<LogService>();
balanceServiceMock = mock<BalanceService>();
transferServiceMock = mock<TransferService>();
Expand All @@ -58,10 +54,6 @@ describe("AddressController", () => {
provide: TransactionService,
useValue: transactionServiceMock,
},
{
provide: TransactionReceiptService,
useValue: transactionReceiptServiceMock,
},
{
provide: LogService,
useValue: logServiceMock,
Expand Down Expand Up @@ -104,9 +96,8 @@ describe("AddressController", () => {

describe("when contract address exists", () => {
const transactionHash = "transactionHash";
const transactionFrom = "transactionFrom";
const creatorAddress = "creatorAddress";
const totalTxCount = 20;
let transactionReceipt;
const addressBalances = {
balances: {
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF": {
Expand All @@ -128,21 +119,13 @@ describe("AddressController", () => {
bytecode: "0x123",
createdInBlockNumber: 30,
creatorTxHash: transactionHash,
creatorAddress: transactionFrom,
creatorAddress,
};
transactionReceipt = mock<TransactionReceipt>({ from: transactionFrom });
(serviceMock.findOne as jest.Mock).mockResolvedValue(addressRecord);
(transactionReceiptServiceMock.findOne as jest.Mock).mockResolvedValue(transactionReceipt);
(transactionServiceMock.count as jest.Mock).mockResolvedValue(totalTxCount);
(balanceServiceMock.getBalances as jest.Mock).mockResolvedValue(addressBalances);
});

it("queries creatorAddress value from transaction receipt", async () => {
await controller.getAddress(blockchainAddress);
expect(transactionReceiptServiceMock.findOne).toHaveBeenCalledTimes(1);
expect(transactionReceiptServiceMock.findOne).toHaveBeenCalledWith(transactionHash, ["from"]);
});

it("queries totalTransactions value from transaction receipt repo with formatted contractAddress", async () => {
await controller.getAddress(blockchainAddress);
expect(transactionServiceMock.count).toHaveBeenCalledTimes(1);
Expand Down
10 changes: 2 additions & 8 deletions packages/api/src/address/address.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { formatHexAddress, buildDateFilter } from "../common/utils";
import { AddressService } from "./address.service";
import { BlockService } from "../block/block.service";
import { TransactionService } from "../transaction/transaction.service";
import { TransactionReceiptService } from "../transaction/transactionReceipt.service";
import { BalanceService } from "../balance/balance.service";
import { AddressType, ContractDto, AccountDto, TokenAddressDto } from "./dtos";
import { LogDto } from "../log/log.dto";
Expand All @@ -37,7 +36,6 @@ export class AddressController {
private readonly addressService: AddressService,
private readonly blockService: BlockService,
private readonly transactionService: TransactionService,
private readonly transactionReceiptService: TransactionReceiptService,
private readonly logService: LogService,
private readonly balanceService: BalanceService,
private readonly transferService: TransferService
Expand Down Expand Up @@ -66,11 +64,7 @@ export class AddressController {
]);

if (addressRecord?.bytecode.length > 2) {
const [txReceipt, totalTransactions] = await Promise.all([
this.transactionReceiptService.findOne(addressRecord.creatorTxHash, ["from"]),
this.transactionService.count({ "from|to": formatHexAddress(address) }),
]);

const totalTransactions = await this.transactionService.count({ "from|to": formatHexAddress(address) });
return {
type: AddressType.Contract,
...addressRecord,
Expand All @@ -79,7 +73,7 @@ export class AddressController {
createdInBlockNumber: addressRecord.createdInBlockNumber,
creatorTxHash: addressRecord.creatorTxHash,
totalTransactions,
creatorAddress: txReceipt.from,
creatorAddress: addressRecord.creatorAddress,
};
}

Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/api/account/account.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { mock } from "jest-mock-extended";
import { BadRequestException, Logger } from "@nestjs/common";
import { L2_ETH_TOKEN_ADDRESS } from "../../common/constants";
import { BlockService } from "../../block/block.service";
import { BlockDetail } from "../../block/blockDetail.entity";
import { BlockDetails } from "../../block/blockDetails.entity";
import { TransactionService } from "../../transaction/transaction.service";
import { BalanceService } from "../../balance/balance.service";
import { TransactionStatus } from "../../transaction/entities/transaction.entity";
Expand Down Expand Up @@ -629,7 +629,7 @@ describe("AccountController", () => {
it("returns blocks list response when block by miner are found", async () => {
jest
.spyOn(blockServiceMock, "findMany")
.mockResolvedValue([{ number: 1, timestamp: new Date("2023-03-03") } as BlockDetail]);
.mockResolvedValue([{ number: 1, timestamp: new Date("2023-03-03") } as BlockDetails]);
const response = await controller.getAccountMinedBlocks(address, {
page: 1,
offset: 10,
Expand Down
57 changes: 54 additions & 3 deletions packages/api/src/api/transaction/transaction.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { mock } from "jest-mock-extended";
import { Logger } from "@nestjs/common";
import { TransactionService } from "../../transaction/transaction.service";
import { TransactionReceiptService } from "../../transaction/transactionReceipt.service";
import { TransactionStatus, Transaction } from "../../transaction/entities/transaction.entity";
import { TransactionStatus } from "../../transaction/entities/transaction.entity";
import { TransactionDetails } from "../../transaction/entities/transactionDetails.entity";
import { TransactionReceipt } from "../../transaction/entities/transactionReceipt.entity";
import { ResponseStatus, ResponseMessage } from "../dtos/common/responseBase.dto";
import { TransactionController } from "./transaction.controller";
Expand Down Expand Up @@ -56,7 +57,7 @@ describe("TransactionController", () => {
it("returns isError as 0 when transaction is successful", async () => {
jest
.spyOn(transactionServiceMock, "findOne")
.mockResolvedValue({ status: TransactionStatus.Included } as Transaction);
.mockResolvedValue({ status: TransactionStatus.Included } as TransactionDetails);

const response = await controller.getTransactionStatus(transactionHash);
expect(response).toEqual({
Expand All @@ -72,7 +73,57 @@ describe("TransactionController", () => {
it("returns isError as 1 when transaction is failed", async () => {
jest
.spyOn(transactionServiceMock, "findOne")
.mockResolvedValue({ status: TransactionStatus.Failed } as Transaction);
.mockResolvedValue({ status: TransactionStatus.Failed } as TransactionDetails);

const response = await controller.getTransactionStatus(transactionHash);
expect(response).toEqual({
status: ResponseStatus.OK,
message: ResponseMessage.OK,
result: {
isError: "1",
errDescription: "",
},
});
});

it("returns transaction error in errDescription when transaction is failed and transaction error is present", async () => {
jest.spyOn(transactionServiceMock, "findOne").mockResolvedValue({
status: TransactionStatus.Failed,
error: "Error",
revertReason: "Reverted",
} as TransactionDetails);

const response = await controller.getTransactionStatus(transactionHash);
expect(response).toEqual({
status: ResponseStatus.OK,
message: ResponseMessage.OK,
result: {
isError: "1",
errDescription: "Error",
},
});
});

it("returns transaction revert reason in errDescription when transaction is failed and transaction revert reason is present", async () => {
jest
.spyOn(transactionServiceMock, "findOne")
.mockResolvedValue({ status: TransactionStatus.Failed, revertReason: "Reverted" } as TransactionDetails);

const response = await controller.getTransactionStatus(transactionHash);
expect(response).toEqual({
status: ResponseStatus.OK,
message: ResponseMessage.OK,
result: {
isError: "1",
errDescription: "Reverted",
},
});
});

it("returns empty errDescription when transaction is failed and transaction error and revert reason are not present", async () => {
jest
.spyOn(transactionServiceMock, "findOne")
.mockResolvedValue({ status: TransactionStatus.Failed } as TransactionDetails);

const response = await controller.getTransactionStatus(transactionHash);
expect(response).toEqual({
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/api/transaction/transaction.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class TransactionController {
message: ResponseMessage.OK,
result: {
isError: hasError ? ResponseStatus.OK : ResponseStatus.NOTOK,
errDescription: "",
errDescription: transaction?.error || transaction?.revertReason || "",
},
};
}
Expand Down
6 changes: 3 additions & 3 deletions packages/api/src/block/block.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { PagingOptionsDto, ListFiltersDto } from "../common/dtos";
import { ApiListPageOkResponse } from "../common/decorators/apiListPageOkResponse";
import { BlockService } from "./block.service";
import { BlockDto } from "./block.dto";
import { BlockDetailDto } from "./blockDetail.dto";
import { BlockDetailsDto } from "./blockDetails.dto";
import { swagger } from "../config/featureFlags";

const entityName = "blocks";
Expand Down Expand Up @@ -48,12 +48,12 @@ export class BlockController {
example: "1",
description: "Block number",
})
@ApiOkResponse({ description: "Block was returned successfully", type: BlockDetailDto })
@ApiOkResponse({ description: "Block was returned successfully", type: BlockDetailsDto })
@ApiBadRequestResponse({ description: "Block number is invalid" })
@ApiNotFoundResponse({ description: "Block with the specified number does not exist" })
public async getBlock(
@Param("blockNumber", new ParseLimitedIntPipe({ min: 0 })) blockNumber: number
): Promise<BlockDetailDto> {
): Promise<BlockDetailsDto> {
const block = await this.blockService.findOne(blockNumber);
if (!block) {
throw new NotFoundException();
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/block/block.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { TypeOrmModule } from "@nestjs/typeorm";
import { BlockService } from "../block/block.service";
import { BlockController } from "./block.controller";
import { Block } from "./block.entity";
import { BlockDetail } from "./blockDetail.entity";
import { BlockDetails } from "./blockDetails.entity";

@Module({
imports: [TypeOrmModule.forFeature([Block, BlockDetail])],
imports: [TypeOrmModule.forFeature([Block, BlockDetails])],
controllers: [BlockController],
providers: [BlockService],
exports: [BlockService],
Expand Down
Loading

0 comments on commit 7d93728

Please sign in to comment.